annotate gcc/tree-ssa-ccp.c @ 117:f81c5aa9f14f

fix
author mir3636
date Tue, 28 Nov 2017 21:17:15 +0900
parents 04ced10e8804
children 84e7813d76e9
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 /* Conditional constant propagation pass for the GNU compiler.
111
kono
parents: 67
diff changeset
2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 This file is part of GCC.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
7
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 Free Software Foundation; either version 3, or (at your option) any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 later version.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
12
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 for more details.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
17
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 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
19 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 /* Conditional constant propagation (CCP) is based on the SSA
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 propagation engine (tree-ssa-propagate.c). Constant assignments of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 the form VAR = CST are propagated from the assignments into uses of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 VAR, which in turn may generate new constants. The simulation uses
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 a four level lattice to keep track of constant values associated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 with SSA names. Given an SSA name V_i, it may take one of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 following values:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 UNINITIALIZED -> the initial state of the value. This value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 is replaced with a correct initial value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 the first time the value is used, so the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 rest of the pass does not need to care about
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 it. Using this value simplifies initialization
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 of the pass, and prevents us from needlessly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 scanning statements that are never reached.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 UNDEFINED -> V_i is a local variable whose definition
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 has not been processed yet. Therefore we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 don't yet know if its value is a constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 or not.
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 CONSTANT -> V_i has been found to hold a constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 value C.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 VARYING -> V_i cannot take a constant value, or if it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 does, it is not possible to determine it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 at compile time.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 The core of SSA-CCP is in ccp_visit_stmt and ccp_visit_phi_node:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 1- In ccp_visit_stmt, we are interested in assignments whose RHS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 evaluates into a constant and conditional jumps whose predicate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 evaluates into a boolean true or false. When an assignment of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 the form V_i = CONST is found, V_i's lattice value is set to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 CONSTANT and CONST is associated with it. This causes the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 propagation engine to add all the SSA edges coming out the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 assignment into the worklists, so that statements that use V_i
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 can be visited.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 If the statement is a conditional with a constant predicate, we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 mark the outgoing edges as executable or not executable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 depending on the predicate's value. This is then used when
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 visiting PHI nodes to know when a PHI argument can be ignored.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
65
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 2- In ccp_visit_phi_node, if all the PHI arguments evaluate to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 same constant C, then the LHS of the PHI is set to C. This
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 evaluation is known as the "meet operation". Since one of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 goals of this evaluation is to optimistically return constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 values as often as possible, it uses two main short cuts:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 - If an argument is flowing in through a non-executable edge, it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 is ignored. This is useful in cases like this:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 if (PRED)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 a_9 = 3;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 a_10 = 100;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 a_11 = PHI (a_9, a_10)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 If PRED is known to always evaluate to false, then we can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 assume that a_11 will always take its value from a_10, meaning
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 that instead of consider it VARYING (a_9 and a_10 have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 different values), we can consider it CONSTANT 100.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 - If an argument has an UNDEFINED value, then it does not affect
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 the outcome of the meet operation. If a variable V_i has an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 UNDEFINED value, it means that either its defining statement
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 hasn't been visited yet or V_i has no defining statement, in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 which case the original symbol 'V' is being used
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 uninitialized. Since 'V' is a local variable, the compiler
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 may assume any initial value for it.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 After propagation, every variable V_i that ends up with a lattice
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 value of CONSTANT will have the associated constant value in the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 array CONST_VAL[i].VALUE. That is fed into substitute_and_fold for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 final substitution and folding.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
111
kono
parents: 67
diff changeset
101 This algorithm uses wide-ints at the max precision of the target.
kono
parents: 67
diff changeset
102 This means that, with one uninteresting exception, variables with
kono
parents: 67
diff changeset
103 UNSIGNED types never go to VARYING because the bits above the
kono
parents: 67
diff changeset
104 precision of the type of the variable are always zero. The
kono
parents: 67
diff changeset
105 uninteresting case is a variable of UNSIGNED type that has the
kono
parents: 67
diff changeset
106 maximum precision of the target. Such variables can go to VARYING,
kono
parents: 67
diff changeset
107 but this causes no loss of infomation since these variables will
kono
parents: 67
diff changeset
108 never be extended.
kono
parents: 67
diff changeset
109
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 References:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 Constant propagation with conditional branches,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
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 Building an Optimizing Compiler,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
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 Advanced Compiler Design and Implementation,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 #include "coretypes.h"
111
kono
parents: 67
diff changeset
124 #include "backend.h"
kono
parents: 67
diff changeset
125 #include "target.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 #include "tree.h"
111
kono
parents: 67
diff changeset
127 #include "gimple.h"
kono
parents: 67
diff changeset
128 #include "tree-pass.h"
kono
parents: 67
diff changeset
129 #include "ssa.h"
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
130 #include "gimple-pretty-print.h"
111
kono
parents: 67
diff changeset
131 #include "fold-const.h"
kono
parents: 67
diff changeset
132 #include "gimple-fold.h"
kono
parents: 67
diff changeset
133 #include "tree-eh.h"
kono
parents: 67
diff changeset
134 #include "gimplify.h"
kono
parents: 67
diff changeset
135 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
136 #include "tree-cfg.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 #include "tree-ssa-propagate.h"
111
kono
parents: 67
diff changeset
138 #include "dbgcnt.h"
kono
parents: 67
diff changeset
139 #include "params.h"
kono
parents: 67
diff changeset
140 #include "builtins.h"
kono
parents: 67
diff changeset
141 #include "tree-chkp.h"
kono
parents: 67
diff changeset
142 #include "cfgloop.h"
kono
parents: 67
diff changeset
143 #include "stor-layout.h"
kono
parents: 67
diff changeset
144 #include "optabs-query.h"
kono
parents: 67
diff changeset
145 #include "tree-ssa-ccp.h"
kono
parents: 67
diff changeset
146 #include "tree-dfa.h"
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
147 #include "diagnostic-core.h"
111
kono
parents: 67
diff changeset
148 #include "stringpool.h"
kono
parents: 67
diff changeset
149 #include "attribs.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 /* Possible lattice values. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 typedef enum
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 UNINITIALIZED,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 UNDEFINED,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 CONSTANT,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 VARYING
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 } ccp_lattice_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
111
kono
parents: 67
diff changeset
160 struct ccp_prop_value_t {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
161 /* Lattice value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
162 ccp_lattice_t lattice_val;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
163
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
164 /* Propagated value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
165 tree value;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
166
111
kono
parents: 67
diff changeset
167 /* Mask that applies to the propagated value during CCP. For X
kono
parents: 67
diff changeset
168 with a CONSTANT lattice value X & ~mask == value & ~mask. The
kono
parents: 67
diff changeset
169 zero bits in the mask cover constant values. The ones mean no
kono
parents: 67
diff changeset
170 information. */
kono
parents: 67
diff changeset
171 widest_int mask;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
172 };
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
173
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 /* Array of propagated constant values. After propagation,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 CONST_VAL[I].VALUE holds the constant value for SSA_NAME(I). If
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 the constant is held in an SSA name representing a memory store
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 (i.e., a VDEF), CONST_VAL[I].MEM_REF will contain the actual
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 memory reference used to store (i.e., the LHS of the assignment
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 doing the store). */
111
kono
parents: 67
diff changeset
180 static ccp_prop_value_t *const_val;
kono
parents: 67
diff changeset
181 static unsigned n_const_val;
kono
parents: 67
diff changeset
182
kono
parents: 67
diff changeset
183 static void canonicalize_value (ccp_prop_value_t *);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
184 static bool ccp_fold_stmt (gimple_stmt_iterator *);
111
kono
parents: 67
diff changeset
185 static void ccp_lattice_meet (ccp_prop_value_t *, ccp_prop_value_t *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 /* Dump constant propagation value VAL to file OUTF prefixed by PREFIX. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 static void
111
kono
parents: 67
diff changeset
190 dump_lattice_value (FILE *outf, const char *prefix, ccp_prop_value_t val)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 switch (val.lattice_val)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 case UNINITIALIZED:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 fprintf (outf, "%sUNINITIALIZED", prefix);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 case UNDEFINED:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 fprintf (outf, "%sUNDEFINED", prefix);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 case VARYING:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 fprintf (outf, "%sVARYING", prefix);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 case CONSTANT:
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
204 if (TREE_CODE (val.value) != INTEGER_CST
111
kono
parents: 67
diff changeset
205 || val.mask == 0)
kono
parents: 67
diff changeset
206 {
kono
parents: 67
diff changeset
207 fprintf (outf, "%sCONSTANT ", prefix);
kono
parents: 67
diff changeset
208 print_generic_expr (outf, val.value, dump_flags);
kono
parents: 67
diff changeset
209 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
210 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
211 {
111
kono
parents: 67
diff changeset
212 widest_int cval = wi::bit_and_not (wi::to_widest (val.value),
kono
parents: 67
diff changeset
213 val.mask);
kono
parents: 67
diff changeset
214 fprintf (outf, "%sCONSTANT ", prefix);
kono
parents: 67
diff changeset
215 print_hex (cval, outf);
kono
parents: 67
diff changeset
216 fprintf (outf, " (");
kono
parents: 67
diff changeset
217 print_hex (val.mask, outf);
kono
parents: 67
diff changeset
218 fprintf (outf, ")");
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
219 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 /* Print lattice value VAL to stderr. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228
111
kono
parents: 67
diff changeset
229 void debug_lattice_value (ccp_prop_value_t val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
231 DEBUG_FUNCTION void
111
kono
parents: 67
diff changeset
232 debug_lattice_value (ccp_prop_value_t val)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 dump_lattice_value (stderr, "", val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 fprintf (stderr, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
111
kono
parents: 67
diff changeset
238 /* Extend NONZERO_BITS to a full mask, based on sgn. */
kono
parents: 67
diff changeset
239
kono
parents: 67
diff changeset
240 static widest_int
kono
parents: 67
diff changeset
241 extend_mask (const wide_int &nonzero_bits, signop sgn)
kono
parents: 67
diff changeset
242 {
kono
parents: 67
diff changeset
243 return widest_int::from (nonzero_bits, sgn);
kono
parents: 67
diff changeset
244 }
0
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 /* Compute a default value for variable VAR and store it in the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 CONST_VAL array. The following rules are used to get default
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 values:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 1- Global and static variables that are declared constant are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 considered CONSTANT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 2- Any other value is considered UNDEFINED. This is useful when
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 considering PHI nodes. PHI arguments that are undefined do not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 change the constant value of the PHI node, which allows for more
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 constants to be propagated.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 3- Variables defined by statements other than assignments and PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 nodes are considered VARYING.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 4- Initial values of variables that are not GIMPLE registers are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 considered VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263
111
kono
parents: 67
diff changeset
264 static ccp_prop_value_t
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 get_default_value (tree var)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 {
111
kono
parents: 67
diff changeset
267 ccp_prop_value_t val = { UNINITIALIZED, NULL_TREE, 0 };
kono
parents: 67
diff changeset
268 gimple *stmt;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
269
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
270 stmt = SSA_NAME_DEF_STMT (var);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
271
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
272 if (gimple_nop_p (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
274 /* Variables defined by an empty statement are those used
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
275 before being initialized. If VAR is a local variable, we
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
276 can assume initially that it is UNDEFINED, otherwise we must
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
277 consider it VARYING. */
111
kono
parents: 67
diff changeset
278 if (!virtual_operand_p (var)
kono
parents: 67
diff changeset
279 && SSA_NAME_VAR (var)
kono
parents: 67
diff changeset
280 && TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
281 val.lattice_val = UNDEFINED;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
282 else
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
283 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
284 val.lattice_val = VARYING;
111
kono
parents: 67
diff changeset
285 val.mask = -1;
kono
parents: 67
diff changeset
286 if (flag_tree_bit_ccp)
kono
parents: 67
diff changeset
287 {
kono
parents: 67
diff changeset
288 wide_int nonzero_bits = get_nonzero_bits (var);
kono
parents: 67
diff changeset
289 if (nonzero_bits != -1)
kono
parents: 67
diff changeset
290 {
kono
parents: 67
diff changeset
291 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
292 val.value = build_zero_cst (TREE_TYPE (var));
kono
parents: 67
diff changeset
293 val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (var)));
kono
parents: 67
diff changeset
294 }
kono
parents: 67
diff changeset
295 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
296 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 }
111
kono
parents: 67
diff changeset
298 else if (is_gimple_assign (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
300 tree cst;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
301 if (gimple_assign_single_p (stmt)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
302 && DECL_P (gimple_assign_rhs1 (stmt))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
303 && (cst = get_symbol_constant_value (gimple_assign_rhs1 (stmt))))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
304 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
305 val.lattice_val = CONSTANT;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
306 val.value = cst;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
307 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
308 else
111
kono
parents: 67
diff changeset
309 {
kono
parents: 67
diff changeset
310 /* Any other variable defined by an assignment is considered
kono
parents: 67
diff changeset
311 UNDEFINED. */
kono
parents: 67
diff changeset
312 val.lattice_val = UNDEFINED;
kono
parents: 67
diff changeset
313 }
kono
parents: 67
diff changeset
314 }
kono
parents: 67
diff changeset
315 else if ((is_gimple_call (stmt)
kono
parents: 67
diff changeset
316 && gimple_call_lhs (stmt) != NULL_TREE)
kono
parents: 67
diff changeset
317 || gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
318 {
kono
parents: 67
diff changeset
319 /* A variable defined by a call or a PHI node is considered
kono
parents: 67
diff changeset
320 UNDEFINED. */
kono
parents: 67
diff changeset
321 val.lattice_val = UNDEFINED;
0
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 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
325 /* Otherwise, VAR will never take on a constant value. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
326 val.lattice_val = VARYING;
111
kono
parents: 67
diff changeset
327 val.mask = -1;
0
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 return val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 /* Get the constant value associated with variable VAR. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335
111
kono
parents: 67
diff changeset
336 static inline ccp_prop_value_t *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 get_value (tree var)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 {
111
kono
parents: 67
diff changeset
339 ccp_prop_value_t *val;
kono
parents: 67
diff changeset
340
kono
parents: 67
diff changeset
341 if (const_val == NULL
kono
parents: 67
diff changeset
342 || SSA_NAME_VERSION (var) >= n_const_val)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 val = &const_val[SSA_NAME_VERSION (var)];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 if (val->lattice_val == UNINITIALIZED)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 *val = get_default_value (var);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348
111
kono
parents: 67
diff changeset
349 canonicalize_value (val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 return val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
354 /* Return the constant tree value associated with VAR. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
355
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
356 static inline tree
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
357 get_constant_value (tree var)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
358 {
111
kono
parents: 67
diff changeset
359 ccp_prop_value_t *val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
360 if (TREE_CODE (var) != SSA_NAME)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
361 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
362 if (is_gimple_min_invariant (var))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
363 return var;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
364 return NULL_TREE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
365 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
366 val = get_value (var);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
367 if (val
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
368 && val->lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
369 && (TREE_CODE (val->value) != INTEGER_CST
111
kono
parents: 67
diff changeset
370 || val->mask == 0))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
371 return val->value;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
372 return NULL_TREE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
373 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
374
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 /* Sets the value associated with VAR to VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 static inline void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 set_value_varying (tree var)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 {
111
kono
parents: 67
diff changeset
380 ccp_prop_value_t *val = &const_val[SSA_NAME_VERSION (var)];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 val->lattice_val = VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 val->value = NULL_TREE;
111
kono
parents: 67
diff changeset
384 val->mask = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386
111
kono
parents: 67
diff changeset
387 /* For integer constants, make sure to drop TREE_OVERFLOW. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 static void
111
kono
parents: 67
diff changeset
390 canonicalize_value (ccp_prop_value_t *val)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 {
111
kono
parents: 67
diff changeset
392 if (val->lattice_val != CONSTANT)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394
111
kono
parents: 67
diff changeset
395 if (TREE_OVERFLOW_P (val->value))
kono
parents: 67
diff changeset
396 val->value = drop_tree_overflow (val->value);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
399 /* Return whether the lattice transition is valid. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
400
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
401 static bool
111
kono
parents: 67
diff changeset
402 valid_lattice_transition (ccp_prop_value_t old_val, ccp_prop_value_t new_val)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
403 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
404 /* Lattice transitions must always be monotonically increasing in
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
405 value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
406 if (old_val.lattice_val < new_val.lattice_val)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
407 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
408
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
409 if (old_val.lattice_val != new_val.lattice_val)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
410 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
411
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
412 if (!old_val.value && !new_val.value)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
413 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
414
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
415 /* Now both lattice values are CONSTANT. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
416
111
kono
parents: 67
diff changeset
417 /* Allow arbitrary copy changes as we might look through PHI <a_1, ...>
kono
parents: 67
diff changeset
418 when only a single copy edge is executable. */
kono
parents: 67
diff changeset
419 if (TREE_CODE (old_val.value) == SSA_NAME
kono
parents: 67
diff changeset
420 && TREE_CODE (new_val.value) == SSA_NAME)
kono
parents: 67
diff changeset
421 return true;
kono
parents: 67
diff changeset
422
kono
parents: 67
diff changeset
423 /* Allow transitioning from a constant to a copy. */
kono
parents: 67
diff changeset
424 if (is_gimple_min_invariant (old_val.value)
kono
parents: 67
diff changeset
425 && TREE_CODE (new_val.value) == SSA_NAME)
kono
parents: 67
diff changeset
426 return true;
kono
parents: 67
diff changeset
427
kono
parents: 67
diff changeset
428 /* Allow transitioning from PHI <&x, not executable> == &x
kono
parents: 67
diff changeset
429 to PHI <&x, &y> == common alignment. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
430 if (TREE_CODE (old_val.value) != INTEGER_CST
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
431 && TREE_CODE (new_val.value) == INTEGER_CST)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
432 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
433
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
434 /* Bit-lattices have to agree in the still valid bits. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
435 if (TREE_CODE (old_val.value) == INTEGER_CST
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
436 && TREE_CODE (new_val.value) == INTEGER_CST)
111
kono
parents: 67
diff changeset
437 return (wi::bit_and_not (wi::to_widest (old_val.value), new_val.mask)
kono
parents: 67
diff changeset
438 == wi::bit_and_not (wi::to_widest (new_val.value), new_val.mask));
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
439
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
440 /* Otherwise constant values have to agree. */
111
kono
parents: 67
diff changeset
441 if (operand_equal_p (old_val.value, new_val.value, 0))
kono
parents: 67
diff changeset
442 return true;
kono
parents: 67
diff changeset
443
kono
parents: 67
diff changeset
444 /* At least the kinds and types should agree now. */
kono
parents: 67
diff changeset
445 if (TREE_CODE (old_val.value) != TREE_CODE (new_val.value)
kono
parents: 67
diff changeset
446 || !types_compatible_p (TREE_TYPE (old_val.value),
kono
parents: 67
diff changeset
447 TREE_TYPE (new_val.value)))
kono
parents: 67
diff changeset
448 return false;
kono
parents: 67
diff changeset
449
kono
parents: 67
diff changeset
450 /* For floats and !HONOR_NANS allow transitions from (partial) NaN
kono
parents: 67
diff changeset
451 to non-NaN. */
kono
parents: 67
diff changeset
452 tree type = TREE_TYPE (new_val.value);
kono
parents: 67
diff changeset
453 if (SCALAR_FLOAT_TYPE_P (type)
kono
parents: 67
diff changeset
454 && !HONOR_NANS (type))
kono
parents: 67
diff changeset
455 {
kono
parents: 67
diff changeset
456 if (REAL_VALUE_ISNAN (TREE_REAL_CST (old_val.value)))
kono
parents: 67
diff changeset
457 return true;
kono
parents: 67
diff changeset
458 }
kono
parents: 67
diff changeset
459 else if (VECTOR_FLOAT_TYPE_P (type)
kono
parents: 67
diff changeset
460 && !HONOR_NANS (type))
kono
parents: 67
diff changeset
461 {
kono
parents: 67
diff changeset
462 for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i)
kono
parents: 67
diff changeset
463 if (!REAL_VALUE_ISNAN
kono
parents: 67
diff changeset
464 (TREE_REAL_CST (VECTOR_CST_ELT (old_val.value, i)))
kono
parents: 67
diff changeset
465 && !operand_equal_p (VECTOR_CST_ELT (old_val.value, i),
kono
parents: 67
diff changeset
466 VECTOR_CST_ELT (new_val.value, i), 0))
kono
parents: 67
diff changeset
467 return false;
kono
parents: 67
diff changeset
468 return true;
kono
parents: 67
diff changeset
469 }
kono
parents: 67
diff changeset
470 else if (COMPLEX_FLOAT_TYPE_P (type)
kono
parents: 67
diff changeset
471 && !HONOR_NANS (type))
kono
parents: 67
diff changeset
472 {
kono
parents: 67
diff changeset
473 if (!REAL_VALUE_ISNAN (TREE_REAL_CST (TREE_REALPART (old_val.value)))
kono
parents: 67
diff changeset
474 && !operand_equal_p (TREE_REALPART (old_val.value),
kono
parents: 67
diff changeset
475 TREE_REALPART (new_val.value), 0))
kono
parents: 67
diff changeset
476 return false;
kono
parents: 67
diff changeset
477 if (!REAL_VALUE_ISNAN (TREE_REAL_CST (TREE_IMAGPART (old_val.value)))
kono
parents: 67
diff changeset
478 && !operand_equal_p (TREE_IMAGPART (old_val.value),
kono
parents: 67
diff changeset
479 TREE_IMAGPART (new_val.value), 0))
kono
parents: 67
diff changeset
480 return false;
kono
parents: 67
diff changeset
481 return true;
kono
parents: 67
diff changeset
482 }
kono
parents: 67
diff changeset
483 return false;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
484 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
485
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 /* Set the value for variable VAR to NEW_VAL. Return true if the new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 value is different from VAR's previous value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 static bool
111
kono
parents: 67
diff changeset
490 set_lattice_value (tree var, ccp_prop_value_t *new_val)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
492 /* We can deal with old UNINITIALIZED values just fine here. */
111
kono
parents: 67
diff changeset
493 ccp_prop_value_t *old_val = &const_val[SSA_NAME_VERSION (var)];
kono
parents: 67
diff changeset
494
kono
parents: 67
diff changeset
495 canonicalize_value (new_val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
497 /* We have to be careful to not go up the bitwise lattice
111
kono
parents: 67
diff changeset
498 represented by the mask. Instead of dropping to VARYING
kono
parents: 67
diff changeset
499 use the meet operator to retain a conservative value.
kono
parents: 67
diff changeset
500 Missed optimizations like PR65851 makes this necessary.
kono
parents: 67
diff changeset
501 It also ensures we converge to a stable lattice solution. */
kono
parents: 67
diff changeset
502 if (old_val->lattice_val != UNINITIALIZED)
kono
parents: 67
diff changeset
503 ccp_lattice_meet (new_val, old_val);
kono
parents: 67
diff changeset
504
kono
parents: 67
diff changeset
505 gcc_checking_assert (valid_lattice_transition (*old_val, *new_val));
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
506
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
507 /* If *OLD_VAL and NEW_VAL are the same, return false to inform the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
508 caller that this was a non-transition. */
111
kono
parents: 67
diff changeset
509 if (old_val->lattice_val != new_val->lattice_val
kono
parents: 67
diff changeset
510 || (new_val->lattice_val == CONSTANT
kono
parents: 67
diff changeset
511 && (TREE_CODE (new_val->value) != TREE_CODE (old_val->value)
kono
parents: 67
diff changeset
512 || (TREE_CODE (new_val->value) == INTEGER_CST
kono
parents: 67
diff changeset
513 && (new_val->mask != old_val->mask
kono
parents: 67
diff changeset
514 || (wi::bit_and_not (wi::to_widest (old_val->value),
kono
parents: 67
diff changeset
515 new_val->mask)
kono
parents: 67
diff changeset
516 != wi::bit_and_not (wi::to_widest (new_val->value),
kono
parents: 67
diff changeset
517 new_val->mask))))
kono
parents: 67
diff changeset
518 || (TREE_CODE (new_val->value) != INTEGER_CST
kono
parents: 67
diff changeset
519 && !operand_equal_p (new_val->value, old_val->value, 0)))))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
520 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
521 /* ??? We would like to delay creation of INTEGER_CSTs from
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
522 partially constants here. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
523
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 {
111
kono
parents: 67
diff changeset
526 dump_lattice_value (dump_file, "Lattice value changed to ", *new_val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 fprintf (dump_file, ". Adding SSA edges to worklist.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529
111
kono
parents: 67
diff changeset
530 *old_val = *new_val;
kono
parents: 67
diff changeset
531
kono
parents: 67
diff changeset
532 gcc_assert (new_val->lattice_val != UNINITIALIZED);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538
111
kono
parents: 67
diff changeset
539 static ccp_prop_value_t get_value_for_expr (tree, bool);
kono
parents: 67
diff changeset
540 static ccp_prop_value_t bit_value_binop (enum tree_code, tree, tree, tree);
kono
parents: 67
diff changeset
541 void bit_value_binop (enum tree_code, signop, int, widest_int *, widest_int *,
kono
parents: 67
diff changeset
542 signop, int, const widest_int &, const widest_int &,
kono
parents: 67
diff changeset
543 signop, int, const widest_int &, const widest_int &);
kono
parents: 67
diff changeset
544
kono
parents: 67
diff changeset
545 /* Return a widest_int that can be used for bitwise simplifications
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
546 from VAL. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
547
111
kono
parents: 67
diff changeset
548 static widest_int
kono
parents: 67
diff changeset
549 value_to_wide_int (ccp_prop_value_t val)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
550 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
551 if (val.value
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
552 && TREE_CODE (val.value) == INTEGER_CST)
111
kono
parents: 67
diff changeset
553 return wi::to_widest (val.value);
kono
parents: 67
diff changeset
554
kono
parents: 67
diff changeset
555 return 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
556 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
557
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
558 /* Return the value for the address expression EXPR based on alignment
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
559 information. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
560
111
kono
parents: 67
diff changeset
561 static ccp_prop_value_t
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
562 get_value_from_alignment (tree expr)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
563 {
111
kono
parents: 67
diff changeset
564 tree type = TREE_TYPE (expr);
kono
parents: 67
diff changeset
565 ccp_prop_value_t val;
kono
parents: 67
diff changeset
566 unsigned HOST_WIDE_INT bitpos;
kono
parents: 67
diff changeset
567 unsigned int align;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
568
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
569 gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
570
111
kono
parents: 67
diff changeset
571 get_pointer_alignment_1 (expr, &align, &bitpos);
kono
parents: 67
diff changeset
572 val.mask = wi::bit_and_not
kono
parents: 67
diff changeset
573 (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
kono
parents: 67
diff changeset
574 ? wi::mask <widest_int> (TYPE_PRECISION (type), false)
kono
parents: 67
diff changeset
575 : -1,
kono
parents: 67
diff changeset
576 align / BITS_PER_UNIT - 1);
kono
parents: 67
diff changeset
577 val.lattice_val
kono
parents: 67
diff changeset
578 = wi::sext (val.mask, TYPE_PRECISION (type)) == -1 ? VARYING : CONSTANT;
kono
parents: 67
diff changeset
579 if (val.lattice_val == CONSTANT)
kono
parents: 67
diff changeset
580 val.value = build_int_cstu (type, bitpos / BITS_PER_UNIT);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
581 else
111
kono
parents: 67
diff changeset
582 val.value = NULL_TREE;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
583
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
584 return val;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
585 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
586
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
587 /* Return the value for the tree operand EXPR. If FOR_BITS_P is true
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
588 return constant bits extracted from alignment information for
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
589 invariant addresses. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
590
111
kono
parents: 67
diff changeset
591 static ccp_prop_value_t
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
592 get_value_for_expr (tree expr, bool for_bits_p)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
593 {
111
kono
parents: 67
diff changeset
594 ccp_prop_value_t val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
595
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
596 if (TREE_CODE (expr) == SSA_NAME)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
597 {
111
kono
parents: 67
diff changeset
598 ccp_prop_value_t *val_ = get_value (expr);
kono
parents: 67
diff changeset
599 if (val_)
kono
parents: 67
diff changeset
600 val = *val_;
kono
parents: 67
diff changeset
601 else
kono
parents: 67
diff changeset
602 {
kono
parents: 67
diff changeset
603 val.lattice_val = VARYING;
kono
parents: 67
diff changeset
604 val.value = NULL_TREE;
kono
parents: 67
diff changeset
605 val.mask = -1;
kono
parents: 67
diff changeset
606 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
607 if (for_bits_p
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
608 && val.lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
609 && TREE_CODE (val.value) == ADDR_EXPR)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
610 val = get_value_from_alignment (val.value);
111
kono
parents: 67
diff changeset
611 /* Fall back to a copy value. */
kono
parents: 67
diff changeset
612 if (!for_bits_p
kono
parents: 67
diff changeset
613 && val.lattice_val == VARYING
kono
parents: 67
diff changeset
614 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr))
kono
parents: 67
diff changeset
615 {
kono
parents: 67
diff changeset
616 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
617 val.value = expr;
kono
parents: 67
diff changeset
618 val.mask = -1;
kono
parents: 67
diff changeset
619 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
620 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
621 else if (is_gimple_min_invariant (expr)
111
kono
parents: 67
diff changeset
622 && (!for_bits_p || TREE_CODE (expr) == INTEGER_CST))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
623 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
624 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
625 val.value = expr;
111
kono
parents: 67
diff changeset
626 val.mask = 0;
kono
parents: 67
diff changeset
627 canonicalize_value (&val);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
628 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
629 else if (TREE_CODE (expr) == ADDR_EXPR)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
630 val = get_value_from_alignment (expr);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
631 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
632 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
633 val.lattice_val = VARYING;
111
kono
parents: 67
diff changeset
634 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
635 val.value = NULL_TREE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
636 }
111
kono
parents: 67
diff changeset
637
kono
parents: 67
diff changeset
638 if (val.lattice_val == VARYING
kono
parents: 67
diff changeset
639 && TYPE_UNSIGNED (TREE_TYPE (expr)))
kono
parents: 67
diff changeset
640 val.mask = wi::zext (val.mask, TYPE_PRECISION (TREE_TYPE (expr)));
kono
parents: 67
diff changeset
641
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
642 return val;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
643 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 /* Return the likely CCP lattice value for STMT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 If STMT has no operands, then return CONSTANT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 Else if undefinedness of operands of STMT cause its value to be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 undefined, then return UNDEFINED.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 Else if any operands of STMT are constants, then return CONSTANT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 Else return VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 static ccp_lattice_t
111
kono
parents: 67
diff changeset
657 likely_value (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 bool has_constant_operand, has_undefined_operand, all_undefined_operands;
111
kono
parents: 67
diff changeset
660 bool has_nsa_operand;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 tree use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 ssa_op_iter iter;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
663 unsigned i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 enum gimple_code code = gimple_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 /* This function appears to be called only for assignments, calls,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 conditionals, and switches, due to the logic in visit_stmt. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 gcc_assert (code == GIMPLE_ASSIGN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 || code == GIMPLE_CALL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 || code == GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 || code == GIMPLE_SWITCH);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 /* If the statement has volatile operands, it won't fold to a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 constant value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 if (gimple_has_volatile_ops (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 return VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 /* Arrive here for more complex cases. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 has_constant_operand = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 has_undefined_operand = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 all_undefined_operands = true;
111
kono
parents: 67
diff changeset
683 has_nsa_operand = false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
684 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 {
111
kono
parents: 67
diff changeset
686 ccp_prop_value_t *val = get_value (use);
kono
parents: 67
diff changeset
687
kono
parents: 67
diff changeset
688 if (val && val->lattice_val == UNDEFINED)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 has_undefined_operand = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 all_undefined_operands = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692
111
kono
parents: 67
diff changeset
693 if (val && val->lattice_val == CONSTANT)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 has_constant_operand = true;
111
kono
parents: 67
diff changeset
695
kono
parents: 67
diff changeset
696 if (SSA_NAME_IS_DEFAULT_DEF (use)
kono
parents: 67
diff changeset
697 || !prop_simulate_again_p (SSA_NAME_DEF_STMT (use)))
kono
parents: 67
diff changeset
698 has_nsa_operand = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
701 /* There may be constants in regular rhs operands. For calls we
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
702 have to ignore lhs, fndecl and static chain, otherwise only
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
703 the lhs. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
704 for (i = (is_gimple_call (stmt) ? 2 : 0) + gimple_has_lhs (stmt);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
705 i < gimple_num_ops (stmt); ++i)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
706 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
707 tree op = gimple_op (stmt, i);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
708 if (!op || TREE_CODE (op) == SSA_NAME)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
709 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
710 if (is_gimple_min_invariant (op))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
711 has_constant_operand = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
712 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
713
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
714 if (has_constant_operand)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
715 all_undefined_operands = false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
716
111
kono
parents: 67
diff changeset
717 if (has_undefined_operand
kono
parents: 67
diff changeset
718 && code == GIMPLE_CALL
kono
parents: 67
diff changeset
719 && gimple_call_internal_p (stmt))
kono
parents: 67
diff changeset
720 switch (gimple_call_internal_fn (stmt))
kono
parents: 67
diff changeset
721 {
kono
parents: 67
diff changeset
722 /* These 3 builtins use the first argument just as a magic
kono
parents: 67
diff changeset
723 way how to find out a decl uid. */
kono
parents: 67
diff changeset
724 case IFN_GOMP_SIMD_LANE:
kono
parents: 67
diff changeset
725 case IFN_GOMP_SIMD_VF:
kono
parents: 67
diff changeset
726 case IFN_GOMP_SIMD_LAST_LANE:
kono
parents: 67
diff changeset
727 has_undefined_operand = false;
kono
parents: 67
diff changeset
728 break;
kono
parents: 67
diff changeset
729 default:
kono
parents: 67
diff changeset
730 break;
kono
parents: 67
diff changeset
731 }
kono
parents: 67
diff changeset
732
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 /* If the operation combines operands like COMPLEX_EXPR make sure to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 not mark the result UNDEFINED if only one part of the result is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 undefined. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 if (has_undefined_operand && all_undefined_operands)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 return UNDEFINED;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 else if (code == GIMPLE_ASSIGN && has_undefined_operand)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 switch (gimple_assign_rhs_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 /* Unary operators are handled with all_undefined_operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 case PLUS_EXPR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 case MINUS_EXPR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 case POINTER_PLUS_EXPR:
111
kono
parents: 67
diff changeset
746 case BIT_XOR_EXPR:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 /* Not MIN_EXPR, MAX_EXPR. One VARYING operand may be selected.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 Not bitwise operators, one VARYING operand may specify the
111
kono
parents: 67
diff changeset
749 result completely.
kono
parents: 67
diff changeset
750 Not logical operators for the same reason, apart from XOR.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 Not COMPLEX_EXPR as one VARYING operand makes the result partly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 not UNDEFINED. Not *DIV_EXPR, comparisons and shifts because
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 the undefined operand may be promoted. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 return UNDEFINED;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755
111
kono
parents: 67
diff changeset
756 case ADDR_EXPR:
kono
parents: 67
diff changeset
757 /* If any part of an address is UNDEFINED, like the index
kono
parents: 67
diff changeset
758 of an ARRAY_EXPR, then treat the result as UNDEFINED. */
kono
parents: 67
diff changeset
759 return UNDEFINED;
kono
parents: 67
diff changeset
760
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 /* If there was an UNDEFINED operand but the result may be not UNDEFINED
111
kono
parents: 67
diff changeset
766 fall back to CONSTANT. During iteration UNDEFINED may still drop
kono
parents: 67
diff changeset
767 to CONSTANT. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 if (has_undefined_operand)
111
kono
parents: 67
diff changeset
769 return CONSTANT;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
770
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
771 /* We do not consider virtual operands here -- load from read-only
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
772 memory may have only VARYING virtual operands, but still be
111
kono
parents: 67
diff changeset
773 constant. Also we can combine the stmt with definitions from
kono
parents: 67
diff changeset
774 operands whose definitions are not simulated again. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 if (has_constant_operand
111
kono
parents: 67
diff changeset
776 || has_nsa_operand
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
777 || gimple_references_memory_p (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 return CONSTANT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 return VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 /* Returns true if STMT cannot be constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 static bool
111
kono
parents: 67
diff changeset
786 surely_varying_stmt_p (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 /* If the statement has operands that we cannot handle, it cannot be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 if (gimple_has_volatile_ops (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 /* If it is a call and does not return a value or is not a
111
kono
parents: 67
diff changeset
794 builtin and not an indirect call or a call to function with
kono
parents: 67
diff changeset
795 assume_aligned/alloc_align attribute, it is varying. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 if (is_gimple_call (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 {
111
kono
parents: 67
diff changeset
798 tree fndecl, fntype = gimple_call_fntype (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 if (!gimple_call_lhs (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
111
kono
parents: 67
diff changeset
801 && !DECL_BUILT_IN (fndecl)
kono
parents: 67
diff changeset
802 && !lookup_attribute ("assume_aligned",
kono
parents: 67
diff changeset
803 TYPE_ATTRIBUTES (fntype))
kono
parents: 67
diff changeset
804 && !lookup_attribute ("alloc_align",
kono
parents: 67
diff changeset
805 TYPE_ATTRIBUTES (fntype))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
809 /* Any other store operation is not interesting. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
810 else if (gimple_vdef (stmt))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
811 return true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
812
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 /* Anything other than assignments and conditional jumps are not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 interesting for CCP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 if (gimple_code (stmt) != GIMPLE_ASSIGN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
816 && gimple_code (stmt) != GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817 && gimple_code (stmt) != GIMPLE_SWITCH
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 && gimple_code (stmt) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 /* Initialize local data structures for CCP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 ccp_initialize (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830
111
kono
parents: 67
diff changeset
831 n_const_val = num_ssa_names;
kono
parents: 67
diff changeset
832 const_val = XCNEWVEC (ccp_prop_value_t, n_const_val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834 /* Initialize simulation flags for PHI nodes and statements. */
111
kono
parents: 67
diff changeset
835 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 gimple_stmt_iterator i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839 for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 {
111
kono
parents: 67
diff changeset
841 gimple *stmt = gsi_stmt (i);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
842 bool is_varying;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
843
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
844 /* If the statement is a control insn, then we do not
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
845 want to avoid simulating the statement once. Failure
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
846 to do so means that those edges will never get added. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
847 if (stmt_ends_bb_p (stmt))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
848 is_varying = false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
849 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
850 is_varying = surely_varying_stmt_p (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
852 if (is_varying)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
853 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
854 tree def;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 ssa_op_iter iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 /* If the statement will not produce a constant, mark
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
858 all its outputs VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
859 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
860 set_value_varying (def);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
861 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
862 prop_set_simulate_again (stmt, !is_varying);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866 /* Now process PHI nodes. We never clear the simulate_again flag on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
867 phi nodes, since we do not know which edges are executable yet,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 except for phi nodes for virtual operands when we do not do store ccp. */
111
kono
parents: 67
diff changeset
869 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
870 {
111
kono
parents: 67
diff changeset
871 gphi_iterator i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
873 for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
874 {
111
kono
parents: 67
diff changeset
875 gphi *phi = i.phi ();
kono
parents: 67
diff changeset
876
kono
parents: 67
diff changeset
877 if (virtual_operand_p (gimple_phi_result (phi)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
878 prop_set_simulate_again (phi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
879 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 prop_set_simulate_again (phi, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
885 /* Debug count support. Reset the values of ssa names
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
886 VARYING when the total number ssa names analyzed is
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
887 beyond the debug count specified. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
888
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
889 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
890 do_dbg_cnt (void)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
891 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
892 unsigned i;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
893 for (i = 0; i < num_ssa_names; i++)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
894 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
895 if (!dbg_cnt (ccp))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
896 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
897 const_val[i].lattice_val = VARYING;
111
kono
parents: 67
diff changeset
898 const_val[i].mask = -1;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
899 const_val[i].value = NULL_TREE;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
900 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
901 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
902 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
903
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
904
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
905 /* Do final substitution of propagated values, cleanup the flowgraph and
111
kono
parents: 67
diff changeset
906 free allocated storage. If NONZERO_P, record nonzero bits.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
907
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 Return TRUE when something was optimized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910 static bool
111
kono
parents: 67
diff changeset
911 ccp_finalize (bool nonzero_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
913 bool something_changed;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
914 unsigned i;
111
kono
parents: 67
diff changeset
915 tree name;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
916
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
917 do_dbg_cnt ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
918
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
919 /* Derive alignment and misalignment information from partially
111
kono
parents: 67
diff changeset
920 constant pointers in the lattice or nonzero bits from partially
kono
parents: 67
diff changeset
921 constant integers. */
kono
parents: 67
diff changeset
922 FOR_EACH_SSA_NAME (i, name, cfun)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
923 {
111
kono
parents: 67
diff changeset
924 ccp_prop_value_t *val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
925 unsigned int tem, align;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
926
111
kono
parents: 67
diff changeset
927 if (!POINTER_TYPE_P (TREE_TYPE (name))
kono
parents: 67
diff changeset
928 && (!INTEGRAL_TYPE_P (TREE_TYPE (name))
kono
parents: 67
diff changeset
929 /* Don't record nonzero bits before IPA to avoid
kono
parents: 67
diff changeset
930 using too much memory. */
kono
parents: 67
diff changeset
931 || !nonzero_p))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
932 continue;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
933
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
934 val = get_value (name);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
935 if (val->lattice_val != CONSTANT
111
kono
parents: 67
diff changeset
936 || TREE_CODE (val->value) != INTEGER_CST
kono
parents: 67
diff changeset
937 || val->mask == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
938 continue;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
939
111
kono
parents: 67
diff changeset
940 if (POINTER_TYPE_P (TREE_TYPE (name)))
kono
parents: 67
diff changeset
941 {
kono
parents: 67
diff changeset
942 /* Trailing mask bits specify the alignment, trailing value
kono
parents: 67
diff changeset
943 bits the misalignment. */
kono
parents: 67
diff changeset
944 tem = val->mask.to_uhwi ();
kono
parents: 67
diff changeset
945 align = least_bit_hwi (tem);
kono
parents: 67
diff changeset
946 if (align > 1)
kono
parents: 67
diff changeset
947 set_ptr_info_alignment (get_ptr_info (name), align,
kono
parents: 67
diff changeset
948 (TREE_INT_CST_LOW (val->value)
kono
parents: 67
diff changeset
949 & (align - 1)));
kono
parents: 67
diff changeset
950 }
kono
parents: 67
diff changeset
951 else
kono
parents: 67
diff changeset
952 {
kono
parents: 67
diff changeset
953 unsigned int precision = TYPE_PRECISION (TREE_TYPE (val->value));
kono
parents: 67
diff changeset
954 wide_int nonzero_bits
kono
parents: 67
diff changeset
955 = (wide_int::from (val->mask, precision, UNSIGNED)
kono
parents: 67
diff changeset
956 | wi::to_wide (val->value));
kono
parents: 67
diff changeset
957 nonzero_bits &= get_nonzero_bits (name);
kono
parents: 67
diff changeset
958 set_nonzero_bits (name, nonzero_bits);
kono
parents: 67
diff changeset
959 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
960 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
961
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962 /* Perform substitutions based on the known constant values. */
111
kono
parents: 67
diff changeset
963 something_changed = substitute_and_fold (get_constant_value, ccp_fold_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 free (const_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 const_val = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 return something_changed;;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
970
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 /* Compute the meet operator between *VAL1 and *VAL2. Store the result
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 in VAL1.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 any M UNDEFINED = any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 any M VARYING = VARYING
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 Ci M Cj = Ci if (i == j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 Ci M Cj = VARYING if (i != j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
979
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 static void
111
kono
parents: 67
diff changeset
981 ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 {
111
kono
parents: 67
diff changeset
983 if (val1->lattice_val == UNDEFINED
kono
parents: 67
diff changeset
984 /* For UNDEFINED M SSA we can't always SSA because its definition
kono
parents: 67
diff changeset
985 may not dominate the PHI node. Doing optimistic copy propagation
kono
parents: 67
diff changeset
986 also causes a lot of gcc.dg/uninit-pred*.c FAILs. */
kono
parents: 67
diff changeset
987 && (val2->lattice_val != CONSTANT
kono
parents: 67
diff changeset
988 || TREE_CODE (val2->value) != SSA_NAME))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 /* UNDEFINED M any = any */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 *val1 = *val2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 }
111
kono
parents: 67
diff changeset
993 else if (val2->lattice_val == UNDEFINED
kono
parents: 67
diff changeset
994 /* See above. */
kono
parents: 67
diff changeset
995 && (val1->lattice_val != CONSTANT
kono
parents: 67
diff changeset
996 || TREE_CODE (val1->value) != SSA_NAME))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 /* any M UNDEFINED = any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 Nothing to do. VAL1 already contains the value we want. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 else if (val1->lattice_val == VARYING
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 || val2->lattice_val == VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 /* any M VARYING = VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006 val1->lattice_val = VARYING;
111
kono
parents: 67
diff changeset
1007 val1->mask = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 val1->value = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010 else if (val1->lattice_val == CONSTANT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 && val2->lattice_val == CONSTANT
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1012 && TREE_CODE (val1->value) == INTEGER_CST
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1013 && TREE_CODE (val2->value) == INTEGER_CST)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1014 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1015 /* Ci M Cj = Ci if (i == j)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1016 Ci M Cj = VARYING if (i != j)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1017
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1018 For INTEGER_CSTs mask unequal bits. If no equal bits remain,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1019 drop to varying. */
111
kono
parents: 67
diff changeset
1020 val1->mask = (val1->mask | val2->mask
kono
parents: 67
diff changeset
1021 | (wi::to_widest (val1->value)
kono
parents: 67
diff changeset
1022 ^ wi::to_widest (val2->value)));
kono
parents: 67
diff changeset
1023 if (wi::sext (val1->mask, TYPE_PRECISION (TREE_TYPE (val1->value))) == -1)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1024 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1025 val1->lattice_val = VARYING;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1026 val1->value = NULL_TREE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1027 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1028 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1029 else if (val1->lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1030 && val2->lattice_val == CONSTANT
111
kono
parents: 67
diff changeset
1031 && operand_equal_p (val1->value, val2->value, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 /* Ci M Cj = Ci if (i == j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034 Ci M Cj = VARYING if (i != j)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1036 VAL1 already contains the value we want for equivalent values. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1037 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1038 else if (val1->lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1039 && val2->lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1040 && (TREE_CODE (val1->value) == ADDR_EXPR
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1041 || TREE_CODE (val2->value) == ADDR_EXPR))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1042 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1043 /* When not equal addresses are involved try meeting for
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1044 alignment. */
111
kono
parents: 67
diff changeset
1045 ccp_prop_value_t tem = *val2;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1046 if (TREE_CODE (val1->value) == ADDR_EXPR)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1047 *val1 = get_value_for_expr (val1->value, true);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1048 if (TREE_CODE (val2->value) == ADDR_EXPR)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1049 tem = get_value_for_expr (val2->value, true);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1050 ccp_lattice_meet (val1, &tem);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1051 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1052 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1053 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1054 /* Any other combination is VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1055 val1->lattice_val = VARYING;
111
kono
parents: 67
diff changeset
1056 val1->mask = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057 val1->value = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 /* Loop through the PHI_NODE's parameters for BLOCK and compare their
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 lattice values to determine PHI_NODE's lattice value. The value of a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 PHI node is determined calling ccp_lattice_meet with all the arguments
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065 of the PHI node that are incoming via executable edges. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 static enum ssa_prop_result
111
kono
parents: 67
diff changeset
1068 ccp_visit_phi_node (gphi *phi)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 unsigned i;
111
kono
parents: 67
diff changeset
1071 ccp_prop_value_t new_val;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1074 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075 fprintf (dump_file, "\nVisiting PHI node: ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076 print_gimple_stmt (dump_file, phi, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078
111
kono
parents: 67
diff changeset
1079 new_val.lattice_val = UNDEFINED;
kono
parents: 67
diff changeset
1080 new_val.value = NULL_TREE;
kono
parents: 67
diff changeset
1081 new_val.mask = 0;
kono
parents: 67
diff changeset
1082
kono
parents: 67
diff changeset
1083 bool first = true;
kono
parents: 67
diff changeset
1084 bool non_exec_edge = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 /* Compute the meet operator over all the PHI arguments flowing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 through executable edges. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089 edge e = gimple_phi_arg_edge (phi, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 fprintf (dump_file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 "\n Argument #%d (%d -> %d %sexecutable)\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 i, e->src->index, e->dest->index,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 /* If the incoming edge is executable, Compute the meet operator for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 the existing value of the PHI node and the current PHI argument. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 if (e->flags & EDGE_EXECUTABLE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 tree arg = gimple_phi_arg (phi, i)->def;
111
kono
parents: 67
diff changeset
1104 ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
kono
parents: 67
diff changeset
1105
kono
parents: 67
diff changeset
1106 if (first)
kono
parents: 67
diff changeset
1107 {
kono
parents: 67
diff changeset
1108 new_val = arg_val;
kono
parents: 67
diff changeset
1109 first = false;
kono
parents: 67
diff changeset
1110 }
kono
parents: 67
diff changeset
1111 else
kono
parents: 67
diff changeset
1112 ccp_lattice_meet (&new_val, &arg_val);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 fprintf (dump_file, "\t");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 print_generic_expr (dump_file, arg, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 dump_lattice_value (dump_file, "\tValue: ", arg_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 fprintf (dump_file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122 if (new_val.lattice_val == VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 }
111
kono
parents: 67
diff changeset
1125 else
kono
parents: 67
diff changeset
1126 non_exec_edge = true;
kono
parents: 67
diff changeset
1127 }
kono
parents: 67
diff changeset
1128
kono
parents: 67
diff changeset
1129 /* In case there were non-executable edges and the value is a copy
kono
parents: 67
diff changeset
1130 make sure its definition dominates the PHI node. */
kono
parents: 67
diff changeset
1131 if (non_exec_edge
kono
parents: 67
diff changeset
1132 && new_val.lattice_val == CONSTANT
kono
parents: 67
diff changeset
1133 && TREE_CODE (new_val.value) == SSA_NAME
kono
parents: 67
diff changeset
1134 && ! SSA_NAME_IS_DEFAULT_DEF (new_val.value)
kono
parents: 67
diff changeset
1135 && ! dominated_by_p (CDI_DOMINATORS, gimple_bb (phi),
kono
parents: 67
diff changeset
1136 gimple_bb (SSA_NAME_DEF_STMT (new_val.value))))
kono
parents: 67
diff changeset
1137 {
kono
parents: 67
diff changeset
1138 new_val.lattice_val = VARYING;
kono
parents: 67
diff changeset
1139 new_val.value = NULL_TREE;
kono
parents: 67
diff changeset
1140 new_val.mask = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 dump_lattice_value (dump_file, "\n PHI node value: ", new_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146 fprintf (dump_file, "\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1147 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149 /* Make the transition to the new value. */
111
kono
parents: 67
diff changeset
1150 if (set_lattice_value (gimple_phi_result (phi), &new_val))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 if (new_val.lattice_val == VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 return SSA_PROP_VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155 return SSA_PROP_INTERESTING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 return SSA_PROP_NOT_INTERESTING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1161 /* Return the constant value for OP or OP otherwise. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1162
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1163 static tree
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1164 valueize_op (tree op)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1165 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1166 if (TREE_CODE (op) == SSA_NAME)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1167 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1168 tree tem = get_constant_value (op);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1169 if (tem)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1170 return tem;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1171 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1172 return op;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1173 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1174
111
kono
parents: 67
diff changeset
1175 /* Return the constant value for OP, but signal to not follow SSA
kono
parents: 67
diff changeset
1176 edges if the definition may be simulated again. */
kono
parents: 67
diff changeset
1177
kono
parents: 67
diff changeset
1178 static tree
kono
parents: 67
diff changeset
1179 valueize_op_1 (tree op)
kono
parents: 67
diff changeset
1180 {
kono
parents: 67
diff changeset
1181 if (TREE_CODE (op) == SSA_NAME)
kono
parents: 67
diff changeset
1182 {
kono
parents: 67
diff changeset
1183 /* If the definition may be simulated again we cannot follow
kono
parents: 67
diff changeset
1184 this SSA edge as the SSA propagator does not necessarily
kono
parents: 67
diff changeset
1185 re-visit the use. */
kono
parents: 67
diff changeset
1186 gimple *def_stmt = SSA_NAME_DEF_STMT (op);
kono
parents: 67
diff changeset
1187 if (!gimple_nop_p (def_stmt)
kono
parents: 67
diff changeset
1188 && prop_simulate_again_p (def_stmt))
kono
parents: 67
diff changeset
1189 return NULL_TREE;
kono
parents: 67
diff changeset
1190 tree tem = get_constant_value (op);
kono
parents: 67
diff changeset
1191 if (tem)
kono
parents: 67
diff changeset
1192 return tem;
kono
parents: 67
diff changeset
1193 }
kono
parents: 67
diff changeset
1194 return op;
kono
parents: 67
diff changeset
1195 }
kono
parents: 67
diff changeset
1196
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197 /* CCP specific front-end to the non-destructive constant folding
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1198 routines.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1200 Attempt to simplify the RHS of STMT knowing that one or more
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201 operands are constants.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1203 If simplification is possible, return the simplified RHS,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 otherwise return the original RHS or NULL_TREE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206 static tree
111
kono
parents: 67
diff changeset
1207 ccp_fold (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1209 location_t loc = gimple_location (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210 switch (gimple_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1211 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 case GIMPLE_COND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214 /* Handle comparison operators that can appear in GIMPLE form. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1215 tree op0 = valueize_op (gimple_cond_lhs (stmt));
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1216 tree op1 = valueize_op (gimple_cond_rhs (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 enum tree_code code = gimple_cond_code (stmt);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1218 return fold_binary_loc (loc, code, boolean_type_node, op0, op1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 case GIMPLE_SWITCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1223 /* Return the constant switch index. */
111
kono
parents: 67
diff changeset
1224 return valueize_op (gimple_switch_index (as_a <gswitch *> (stmt)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226
111
kono
parents: 67
diff changeset
1227 case GIMPLE_ASSIGN:
kono
parents: 67
diff changeset
1228 case GIMPLE_CALL:
kono
parents: 67
diff changeset
1229 return gimple_fold_stmt_to_constant_1 (stmt,
kono
parents: 67
diff changeset
1230 valueize_op, valueize_op_1);
kono
parents: 67
diff changeset
1231
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1233 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1237 /* Apply the operation CODE in type TYPE to the value, mask pair
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1238 RVAL and RMASK representing a value of type RTYPE and set
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1239 the value, mask pair *VAL and *MASK to the result. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1240
111
kono
parents: 67
diff changeset
1241 void
kono
parents: 67
diff changeset
1242 bit_value_unop (enum tree_code code, signop type_sgn, int type_precision,
kono
parents: 67
diff changeset
1243 widest_int *val, widest_int *mask,
kono
parents: 67
diff changeset
1244 signop rtype_sgn, int rtype_precision,
kono
parents: 67
diff changeset
1245 const widest_int &rval, const widest_int &rmask)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1246 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1247 switch (code)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1248 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1249 case BIT_NOT_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1250 *mask = rmask;
111
kono
parents: 67
diff changeset
1251 *val = ~rval;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1252 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1253
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1254 case NEGATE_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1255 {
111
kono
parents: 67
diff changeset
1256 widest_int temv, temm;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1257 /* Return ~rval + 1. */
111
kono
parents: 67
diff changeset
1258 bit_value_unop (BIT_NOT_EXPR, type_sgn, type_precision, &temv, &temm,
kono
parents: 67
diff changeset
1259 type_sgn, type_precision, rval, rmask);
kono
parents: 67
diff changeset
1260 bit_value_binop (PLUS_EXPR, type_sgn, type_precision, val, mask,
kono
parents: 67
diff changeset
1261 type_sgn, type_precision, temv, temm,
kono
parents: 67
diff changeset
1262 type_sgn, type_precision, 1, 0);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1263 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1264 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1265
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1266 CASE_CONVERT:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1267 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1268 /* First extend mask and value according to the original type. */
111
kono
parents: 67
diff changeset
1269 *mask = wi::ext (rmask, rtype_precision, rtype_sgn);
kono
parents: 67
diff changeset
1270 *val = wi::ext (rval, rtype_precision, rtype_sgn);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1271
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1272 /* Then extend mask and value according to the target type. */
111
kono
parents: 67
diff changeset
1273 *mask = wi::ext (*mask, type_precision, type_sgn);
kono
parents: 67
diff changeset
1274 *val = wi::ext (*val, type_precision, type_sgn);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1275 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1276 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1277
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1278 default:
111
kono
parents: 67
diff changeset
1279 *mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1280 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1281 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1282 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1283
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1284 /* Apply the operation CODE in type TYPE to the value, mask pairs
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1285 R1VAL, R1MASK and R2VAL, R2MASK representing a values of type R1TYPE
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1286 and R2TYPE and set the value, mask pair *VAL and *MASK to the result. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1287
111
kono
parents: 67
diff changeset
1288 void
kono
parents: 67
diff changeset
1289 bit_value_binop (enum tree_code code, signop sgn, int width,
kono
parents: 67
diff changeset
1290 widest_int *val, widest_int *mask,
kono
parents: 67
diff changeset
1291 signop r1type_sgn, int r1type_precision,
kono
parents: 67
diff changeset
1292 const widest_int &r1val, const widest_int &r1mask,
kono
parents: 67
diff changeset
1293 signop r2type_sgn, int r2type_precision,
kono
parents: 67
diff changeset
1294 const widest_int &r2val, const widest_int &r2mask)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1295 {
111
kono
parents: 67
diff changeset
1296 bool swap_p = false;
kono
parents: 67
diff changeset
1297
kono
parents: 67
diff changeset
1298 /* Assume we'll get a constant result. Use an initial non varying
kono
parents: 67
diff changeset
1299 value, we fall back to varying in the end if necessary. */
kono
parents: 67
diff changeset
1300 *mask = -1;
kono
parents: 67
diff changeset
1301
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1302 switch (code)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1303 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1304 case BIT_AND_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1305 /* The mask is constant where there is a known not
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1306 set bit, (m1 | m2) & ((v1 | m1) & (v2 | m2)) */
111
kono
parents: 67
diff changeset
1307 *mask = (r1mask | r2mask) & (r1val | r1mask) & (r2val | r2mask);
kono
parents: 67
diff changeset
1308 *val = r1val & r2val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1309 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1310
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1311 case BIT_IOR_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1312 /* The mask is constant where there is a known
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1313 set bit, (m1 | m2) & ~((v1 & ~m1) | (v2 & ~m2)). */
111
kono
parents: 67
diff changeset
1314 *mask = wi::bit_and_not (r1mask | r2mask,
kono
parents: 67
diff changeset
1315 wi::bit_and_not (r1val, r1mask)
kono
parents: 67
diff changeset
1316 | wi::bit_and_not (r2val, r2mask));
kono
parents: 67
diff changeset
1317 *val = r1val | r2val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1318 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1319
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1320 case BIT_XOR_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1321 /* m1 | m2 */
111
kono
parents: 67
diff changeset
1322 *mask = r1mask | r2mask;
kono
parents: 67
diff changeset
1323 *val = r1val ^ r2val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1324 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1325
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1326 case LROTATE_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1327 case RROTATE_EXPR:
111
kono
parents: 67
diff changeset
1328 if (r2mask == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1329 {
111
kono
parents: 67
diff changeset
1330 widest_int shift = r2val;
kono
parents: 67
diff changeset
1331 if (shift == 0)
kono
parents: 67
diff changeset
1332 {
kono
parents: 67
diff changeset
1333 *mask = r1mask;
kono
parents: 67
diff changeset
1334 *val = r1val;
kono
parents: 67
diff changeset
1335 }
kono
parents: 67
diff changeset
1336 else
kono
parents: 67
diff changeset
1337 {
kono
parents: 67
diff changeset
1338 if (wi::neg_p (shift))
kono
parents: 67
diff changeset
1339 {
kono
parents: 67
diff changeset
1340 shift = -shift;
kono
parents: 67
diff changeset
1341 if (code == RROTATE_EXPR)
kono
parents: 67
diff changeset
1342 code = LROTATE_EXPR;
kono
parents: 67
diff changeset
1343 else
kono
parents: 67
diff changeset
1344 code = RROTATE_EXPR;
kono
parents: 67
diff changeset
1345 }
kono
parents: 67
diff changeset
1346 if (code == RROTATE_EXPR)
kono
parents: 67
diff changeset
1347 {
kono
parents: 67
diff changeset
1348 *mask = wi::rrotate (r1mask, shift, width);
kono
parents: 67
diff changeset
1349 *val = wi::rrotate (r1val, shift, width);
kono
parents: 67
diff changeset
1350 }
kono
parents: 67
diff changeset
1351 else
kono
parents: 67
diff changeset
1352 {
kono
parents: 67
diff changeset
1353 *mask = wi::lrotate (r1mask, shift, width);
kono
parents: 67
diff changeset
1354 *val = wi::lrotate (r1val, shift, width);
kono
parents: 67
diff changeset
1355 }
kono
parents: 67
diff changeset
1356 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1357 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1358 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1359
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1360 case LSHIFT_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1361 case RSHIFT_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1362 /* ??? We can handle partially known shift counts if we know
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1363 its sign. That way we can tell that (x << (y | 8)) & 255
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1364 is zero. */
111
kono
parents: 67
diff changeset
1365 if (r2mask == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1366 {
111
kono
parents: 67
diff changeset
1367 widest_int shift = r2val;
kono
parents: 67
diff changeset
1368 if (shift == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1369 {
111
kono
parents: 67
diff changeset
1370 *mask = r1mask;
kono
parents: 67
diff changeset
1371 *val = r1val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1372 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1373 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1374 {
111
kono
parents: 67
diff changeset
1375 if (wi::neg_p (shift))
kono
parents: 67
diff changeset
1376 {
kono
parents: 67
diff changeset
1377 shift = -shift;
kono
parents: 67
diff changeset
1378 if (code == RSHIFT_EXPR)
kono
parents: 67
diff changeset
1379 code = LSHIFT_EXPR;
kono
parents: 67
diff changeset
1380 else
kono
parents: 67
diff changeset
1381 code = RSHIFT_EXPR;
kono
parents: 67
diff changeset
1382 }
kono
parents: 67
diff changeset
1383 if (code == RSHIFT_EXPR)
kono
parents: 67
diff changeset
1384 {
kono
parents: 67
diff changeset
1385 *mask = wi::rshift (wi::ext (r1mask, width, sgn), shift, sgn);
kono
parents: 67
diff changeset
1386 *val = wi::rshift (wi::ext (r1val, width, sgn), shift, sgn);
kono
parents: 67
diff changeset
1387 }
kono
parents: 67
diff changeset
1388 else
kono
parents: 67
diff changeset
1389 {
kono
parents: 67
diff changeset
1390 *mask = wi::ext (r1mask << shift, width, sgn);
kono
parents: 67
diff changeset
1391 *val = wi::ext (r1val << shift, width, sgn);
kono
parents: 67
diff changeset
1392 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1393 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1394 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1395 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1396
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1397 case PLUS_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1398 case POINTER_PLUS_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1399 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1400 /* Do the addition with unknown bits set to zero, to give carry-ins of
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1401 zero wherever possible. */
111
kono
parents: 67
diff changeset
1402 widest_int lo = (wi::bit_and_not (r1val, r1mask)
kono
parents: 67
diff changeset
1403 + wi::bit_and_not (r2val, r2mask));
kono
parents: 67
diff changeset
1404 lo = wi::ext (lo, width, sgn);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1405 /* Do the addition with unknown bits set to one, to give carry-ins of
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1406 one wherever possible. */
111
kono
parents: 67
diff changeset
1407 widest_int hi = (r1val | r1mask) + (r2val | r2mask);
kono
parents: 67
diff changeset
1408 hi = wi::ext (hi, width, sgn);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1409 /* Each bit in the result is known if (a) the corresponding bits in
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1410 both inputs are known, and (b) the carry-in to that bit position
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1411 is known. We can check condition (b) by seeing if we got the same
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1412 result with minimised carries as with maximised carries. */
111
kono
parents: 67
diff changeset
1413 *mask = r1mask | r2mask | (lo ^ hi);
kono
parents: 67
diff changeset
1414 *mask = wi::ext (*mask, width, sgn);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1415 /* It shouldn't matter whether we choose lo or hi here. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1416 *val = lo;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1417 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1418 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1419
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1420 case MINUS_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1421 {
111
kono
parents: 67
diff changeset
1422 widest_int temv, temm;
kono
parents: 67
diff changeset
1423 bit_value_unop (NEGATE_EXPR, r2type_sgn, r2type_precision, &temv, &temm,
kono
parents: 67
diff changeset
1424 r2type_sgn, r2type_precision, r2val, r2mask);
kono
parents: 67
diff changeset
1425 bit_value_binop (PLUS_EXPR, sgn, width, val, mask,
kono
parents: 67
diff changeset
1426 r1type_sgn, r1type_precision, r1val, r1mask,
kono
parents: 67
diff changeset
1427 r2type_sgn, r2type_precision, temv, temm);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1428 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1429 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1430
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1431 case MULT_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1432 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1433 /* Just track trailing zeros in both operands and transfer
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1434 them to the other. */
111
kono
parents: 67
diff changeset
1435 int r1tz = wi::ctz (r1val | r1mask);
kono
parents: 67
diff changeset
1436 int r2tz = wi::ctz (r2val | r2mask);
kono
parents: 67
diff changeset
1437 if (r1tz + r2tz >= width)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1438 {
111
kono
parents: 67
diff changeset
1439 *mask = 0;
kono
parents: 67
diff changeset
1440 *val = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1441 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1442 else if (r1tz + r2tz > 0)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1443 {
111
kono
parents: 67
diff changeset
1444 *mask = wi::ext (wi::mask <widest_int> (r1tz + r2tz, true),
kono
parents: 67
diff changeset
1445 width, sgn);
kono
parents: 67
diff changeset
1446 *val = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1447 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1448 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1449 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1450
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1451 case EQ_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1452 case NE_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1453 {
111
kono
parents: 67
diff changeset
1454 widest_int m = r1mask | r2mask;
kono
parents: 67
diff changeset
1455 if (wi::bit_and_not (r1val, m) != wi::bit_and_not (r2val, m))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1456 {
111
kono
parents: 67
diff changeset
1457 *mask = 0;
kono
parents: 67
diff changeset
1458 *val = ((code == EQ_EXPR) ? 0 : 1);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1459 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1460 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1461 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1462 /* We know the result of a comparison is always one or zero. */
111
kono
parents: 67
diff changeset
1463 *mask = 1;
kono
parents: 67
diff changeset
1464 *val = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1465 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1466 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1467 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1468
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1469 case GE_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1470 case GT_EXPR:
111
kono
parents: 67
diff changeset
1471 swap_p = true;
kono
parents: 67
diff changeset
1472 code = swap_tree_comparison (code);
kono
parents: 67
diff changeset
1473 /* Fall through. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1474 case LT_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1475 case LE_EXPR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1476 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1477 int minmax, maxmin;
111
kono
parents: 67
diff changeset
1478
kono
parents: 67
diff changeset
1479 const widest_int &o1val = swap_p ? r2val : r1val;
kono
parents: 67
diff changeset
1480 const widest_int &o1mask = swap_p ? r2mask : r1mask;
kono
parents: 67
diff changeset
1481 const widest_int &o2val = swap_p ? r1val : r2val;
kono
parents: 67
diff changeset
1482 const widest_int &o2mask = swap_p ? r1mask : r2mask;
kono
parents: 67
diff changeset
1483
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1484 /* If the most significant bits are not known we know nothing. */
111
kono
parents: 67
diff changeset
1485 if (wi::neg_p (o1mask) || wi::neg_p (o2mask))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1486 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1487
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1488 /* For comparisons the signedness is in the comparison operands. */
111
kono
parents: 67
diff changeset
1489 sgn = r1type_sgn;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1490
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1491 /* If we know the most significant bits we know the values
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1492 value ranges by means of treating varying bits as zero
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1493 or one. Do a cross comparison of the max/min pairs. */
111
kono
parents: 67
diff changeset
1494 maxmin = wi::cmp (o1val | o1mask,
kono
parents: 67
diff changeset
1495 wi::bit_and_not (o2val, o2mask), sgn);
kono
parents: 67
diff changeset
1496 minmax = wi::cmp (wi::bit_and_not (o1val, o1mask),
kono
parents: 67
diff changeset
1497 o2val | o2mask, sgn);
kono
parents: 67
diff changeset
1498 if (maxmin < 0) /* o1 is less than o2. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1499 {
111
kono
parents: 67
diff changeset
1500 *mask = 0;
kono
parents: 67
diff changeset
1501 *val = 1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1502 }
111
kono
parents: 67
diff changeset
1503 else if (minmax > 0) /* o1 is not less or equal to o2. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1504 {
111
kono
parents: 67
diff changeset
1505 *mask = 0;
kono
parents: 67
diff changeset
1506 *val = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1507 }
111
kono
parents: 67
diff changeset
1508 else if (maxmin == minmax) /* o1 and o2 are equal. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1509 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1510 /* This probably should never happen as we'd have
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1511 folded the thing during fully constant value folding. */
111
kono
parents: 67
diff changeset
1512 *mask = 0;
kono
parents: 67
diff changeset
1513 *val = (code == LE_EXPR ? 1 : 0);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1514 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1515 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1516 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1517 /* We know the result of a comparison is always one or zero. */
111
kono
parents: 67
diff changeset
1518 *mask = 1;
kono
parents: 67
diff changeset
1519 *val = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1520 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1521 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1522 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1523
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1524 default:;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1525 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1526 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1527
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1528 /* Return the propagation value when applying the operation CODE to
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1529 the value RHS yielding type TYPE. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1530
111
kono
parents: 67
diff changeset
1531 static ccp_prop_value_t
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1532 bit_value_unop (enum tree_code code, tree type, tree rhs)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1533 {
111
kono
parents: 67
diff changeset
1534 ccp_prop_value_t rval = get_value_for_expr (rhs, true);
kono
parents: 67
diff changeset
1535 widest_int value, mask;
kono
parents: 67
diff changeset
1536 ccp_prop_value_t val;
kono
parents: 67
diff changeset
1537
kono
parents: 67
diff changeset
1538 if (rval.lattice_val == UNDEFINED)
kono
parents: 67
diff changeset
1539 return rval;
kono
parents: 67
diff changeset
1540
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1541 gcc_assert ((rval.lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1542 && TREE_CODE (rval.value) == INTEGER_CST)
111
kono
parents: 67
diff changeset
1543 || wi::sext (rval.mask, TYPE_PRECISION (TREE_TYPE (rhs))) == -1);
kono
parents: 67
diff changeset
1544 bit_value_unop (code, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask,
kono
parents: 67
diff changeset
1545 TYPE_SIGN (TREE_TYPE (rhs)), TYPE_PRECISION (TREE_TYPE (rhs)),
kono
parents: 67
diff changeset
1546 value_to_wide_int (rval), rval.mask);
kono
parents: 67
diff changeset
1547 if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1548 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1549 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1550 val.mask = mask;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1551 /* ??? Delay building trees here. */
111
kono
parents: 67
diff changeset
1552 val.value = wide_int_to_tree (type, value);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1553 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1554 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1555 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1556 val.lattice_val = VARYING;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1557 val.value = NULL_TREE;
111
kono
parents: 67
diff changeset
1558 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1559 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1560 return val;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1561 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1562
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1563 /* Return the propagation value when applying the operation CODE to
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1564 the values RHS1 and RHS2 yielding type TYPE. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1565
111
kono
parents: 67
diff changeset
1566 static ccp_prop_value_t
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1567 bit_value_binop (enum tree_code code, tree type, tree rhs1, tree rhs2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1568 {
111
kono
parents: 67
diff changeset
1569 ccp_prop_value_t r1val = get_value_for_expr (rhs1, true);
kono
parents: 67
diff changeset
1570 ccp_prop_value_t r2val = get_value_for_expr (rhs2, true);
kono
parents: 67
diff changeset
1571 widest_int value, mask;
kono
parents: 67
diff changeset
1572 ccp_prop_value_t val;
kono
parents: 67
diff changeset
1573
kono
parents: 67
diff changeset
1574 if (r1val.lattice_val == UNDEFINED
kono
parents: 67
diff changeset
1575 || r2val.lattice_val == UNDEFINED)
kono
parents: 67
diff changeset
1576 {
kono
parents: 67
diff changeset
1577 val.lattice_val = VARYING;
kono
parents: 67
diff changeset
1578 val.value = NULL_TREE;
kono
parents: 67
diff changeset
1579 val.mask = -1;
kono
parents: 67
diff changeset
1580 return val;
kono
parents: 67
diff changeset
1581 }
kono
parents: 67
diff changeset
1582
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1583 gcc_assert ((r1val.lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1584 && TREE_CODE (r1val.value) == INTEGER_CST)
111
kono
parents: 67
diff changeset
1585 || wi::sext (r1val.mask,
kono
parents: 67
diff changeset
1586 TYPE_PRECISION (TREE_TYPE (rhs1))) == -1);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1587 gcc_assert ((r2val.lattice_val == CONSTANT
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1588 && TREE_CODE (r2val.value) == INTEGER_CST)
111
kono
parents: 67
diff changeset
1589 || wi::sext (r2val.mask,
kono
parents: 67
diff changeset
1590 TYPE_PRECISION (TREE_TYPE (rhs2))) == -1);
kono
parents: 67
diff changeset
1591 bit_value_binop (code, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask,
kono
parents: 67
diff changeset
1592 TYPE_SIGN (TREE_TYPE (rhs1)), TYPE_PRECISION (TREE_TYPE (rhs1)),
kono
parents: 67
diff changeset
1593 value_to_wide_int (r1val), r1val.mask,
kono
parents: 67
diff changeset
1594 TYPE_SIGN (TREE_TYPE (rhs2)), TYPE_PRECISION (TREE_TYPE (rhs2)),
kono
parents: 67
diff changeset
1595 value_to_wide_int (r2val), r2val.mask);
kono
parents: 67
diff changeset
1596
kono
parents: 67
diff changeset
1597 if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1598 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1599 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1600 val.mask = mask;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1601 /* ??? Delay building trees here. */
111
kono
parents: 67
diff changeset
1602 val.value = wide_int_to_tree (type, value);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1603 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1604 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1605 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1606 val.lattice_val = VARYING;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1607 val.value = NULL_TREE;
111
kono
parents: 67
diff changeset
1608 val.mask = -1;
kono
parents: 67
diff changeset
1609 }
kono
parents: 67
diff changeset
1610 return val;
kono
parents: 67
diff changeset
1611 }
kono
parents: 67
diff changeset
1612
kono
parents: 67
diff changeset
1613 /* Return the propagation value for __builtin_assume_aligned
kono
parents: 67
diff changeset
1614 and functions with assume_aligned or alloc_aligned attribute.
kono
parents: 67
diff changeset
1615 For __builtin_assume_aligned, ATTR is NULL_TREE,
kono
parents: 67
diff changeset
1616 for assume_aligned attribute ATTR is non-NULL and ALLOC_ALIGNED
kono
parents: 67
diff changeset
1617 is false, for alloc_aligned attribute ATTR is non-NULL and
kono
parents: 67
diff changeset
1618 ALLOC_ALIGNED is true. */
kono
parents: 67
diff changeset
1619
kono
parents: 67
diff changeset
1620 static ccp_prop_value_t
kono
parents: 67
diff changeset
1621 bit_value_assume_aligned (gimple *stmt, tree attr, ccp_prop_value_t ptrval,
kono
parents: 67
diff changeset
1622 bool alloc_aligned)
kono
parents: 67
diff changeset
1623 {
kono
parents: 67
diff changeset
1624 tree align, misalign = NULL_TREE, type;
kono
parents: 67
diff changeset
1625 unsigned HOST_WIDE_INT aligni, misaligni = 0;
kono
parents: 67
diff changeset
1626 ccp_prop_value_t alignval;
kono
parents: 67
diff changeset
1627 widest_int value, mask;
kono
parents: 67
diff changeset
1628 ccp_prop_value_t val;
kono
parents: 67
diff changeset
1629
kono
parents: 67
diff changeset
1630 if (attr == NULL_TREE)
kono
parents: 67
diff changeset
1631 {
kono
parents: 67
diff changeset
1632 tree ptr = gimple_call_arg (stmt, 0);
kono
parents: 67
diff changeset
1633 type = TREE_TYPE (ptr);
kono
parents: 67
diff changeset
1634 ptrval = get_value_for_expr (ptr, true);
kono
parents: 67
diff changeset
1635 }
kono
parents: 67
diff changeset
1636 else
kono
parents: 67
diff changeset
1637 {
kono
parents: 67
diff changeset
1638 tree lhs = gimple_call_lhs (stmt);
kono
parents: 67
diff changeset
1639 type = TREE_TYPE (lhs);
kono
parents: 67
diff changeset
1640 }
kono
parents: 67
diff changeset
1641
kono
parents: 67
diff changeset
1642 if (ptrval.lattice_val == UNDEFINED)
kono
parents: 67
diff changeset
1643 return ptrval;
kono
parents: 67
diff changeset
1644 gcc_assert ((ptrval.lattice_val == CONSTANT
kono
parents: 67
diff changeset
1645 && TREE_CODE (ptrval.value) == INTEGER_CST)
kono
parents: 67
diff changeset
1646 || wi::sext (ptrval.mask, TYPE_PRECISION (type)) == -1);
kono
parents: 67
diff changeset
1647 if (attr == NULL_TREE)
kono
parents: 67
diff changeset
1648 {
kono
parents: 67
diff changeset
1649 /* Get aligni and misaligni from __builtin_assume_aligned. */
kono
parents: 67
diff changeset
1650 align = gimple_call_arg (stmt, 1);
kono
parents: 67
diff changeset
1651 if (!tree_fits_uhwi_p (align))
kono
parents: 67
diff changeset
1652 return ptrval;
kono
parents: 67
diff changeset
1653 aligni = tree_to_uhwi (align);
kono
parents: 67
diff changeset
1654 if (gimple_call_num_args (stmt) > 2)
kono
parents: 67
diff changeset
1655 {
kono
parents: 67
diff changeset
1656 misalign = gimple_call_arg (stmt, 2);
kono
parents: 67
diff changeset
1657 if (!tree_fits_uhwi_p (misalign))
kono
parents: 67
diff changeset
1658 return ptrval;
kono
parents: 67
diff changeset
1659 misaligni = tree_to_uhwi (misalign);
kono
parents: 67
diff changeset
1660 }
kono
parents: 67
diff changeset
1661 }
kono
parents: 67
diff changeset
1662 else
kono
parents: 67
diff changeset
1663 {
kono
parents: 67
diff changeset
1664 /* Get aligni and misaligni from assume_aligned or
kono
parents: 67
diff changeset
1665 alloc_align attributes. */
kono
parents: 67
diff changeset
1666 if (TREE_VALUE (attr) == NULL_TREE)
kono
parents: 67
diff changeset
1667 return ptrval;
kono
parents: 67
diff changeset
1668 attr = TREE_VALUE (attr);
kono
parents: 67
diff changeset
1669 align = TREE_VALUE (attr);
kono
parents: 67
diff changeset
1670 if (!tree_fits_uhwi_p (align))
kono
parents: 67
diff changeset
1671 return ptrval;
kono
parents: 67
diff changeset
1672 aligni = tree_to_uhwi (align);
kono
parents: 67
diff changeset
1673 if (alloc_aligned)
kono
parents: 67
diff changeset
1674 {
kono
parents: 67
diff changeset
1675 if (aligni == 0 || aligni > gimple_call_num_args (stmt))
kono
parents: 67
diff changeset
1676 return ptrval;
kono
parents: 67
diff changeset
1677 align = gimple_call_arg (stmt, aligni - 1);
kono
parents: 67
diff changeset
1678 if (!tree_fits_uhwi_p (align))
kono
parents: 67
diff changeset
1679 return ptrval;
kono
parents: 67
diff changeset
1680 aligni = tree_to_uhwi (align);
kono
parents: 67
diff changeset
1681 }
kono
parents: 67
diff changeset
1682 else if (TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr)))
kono
parents: 67
diff changeset
1683 {
kono
parents: 67
diff changeset
1684 misalign = TREE_VALUE (TREE_CHAIN (attr));
kono
parents: 67
diff changeset
1685 if (!tree_fits_uhwi_p (misalign))
kono
parents: 67
diff changeset
1686 return ptrval;
kono
parents: 67
diff changeset
1687 misaligni = tree_to_uhwi (misalign);
kono
parents: 67
diff changeset
1688 }
kono
parents: 67
diff changeset
1689 }
kono
parents: 67
diff changeset
1690 if (aligni <= 1 || (aligni & (aligni - 1)) != 0 || misaligni >= aligni)
kono
parents: 67
diff changeset
1691 return ptrval;
kono
parents: 67
diff changeset
1692
kono
parents: 67
diff changeset
1693 align = build_int_cst_type (type, -aligni);
kono
parents: 67
diff changeset
1694 alignval = get_value_for_expr (align, true);
kono
parents: 67
diff changeset
1695 bit_value_binop (BIT_AND_EXPR, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask,
kono
parents: 67
diff changeset
1696 TYPE_SIGN (type), TYPE_PRECISION (type), value_to_wide_int (ptrval), ptrval.mask,
kono
parents: 67
diff changeset
1697 TYPE_SIGN (type), TYPE_PRECISION (type), value_to_wide_int (alignval), alignval.mask);
kono
parents: 67
diff changeset
1698
kono
parents: 67
diff changeset
1699 if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
kono
parents: 67
diff changeset
1700 {
kono
parents: 67
diff changeset
1701 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
1702 val.mask = mask;
kono
parents: 67
diff changeset
1703 gcc_assert ((mask.to_uhwi () & (aligni - 1)) == 0);
kono
parents: 67
diff changeset
1704 gcc_assert ((value.to_uhwi () & (aligni - 1)) == 0);
kono
parents: 67
diff changeset
1705 value |= misaligni;
kono
parents: 67
diff changeset
1706 /* ??? Delay building trees here. */
kono
parents: 67
diff changeset
1707 val.value = wide_int_to_tree (type, value);
kono
parents: 67
diff changeset
1708 }
kono
parents: 67
diff changeset
1709 else
kono
parents: 67
diff changeset
1710 {
kono
parents: 67
diff changeset
1711 val.lattice_val = VARYING;
kono
parents: 67
diff changeset
1712 val.value = NULL_TREE;
kono
parents: 67
diff changeset
1713 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1714 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1715 return val;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1716 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1717
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1718 /* Evaluate statement STMT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1719 Valid only for assignments, calls, conditionals, and switches. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1720
111
kono
parents: 67
diff changeset
1721 static ccp_prop_value_t
kono
parents: 67
diff changeset
1722 evaluate_stmt (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1723 {
111
kono
parents: 67
diff changeset
1724 ccp_prop_value_t val;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1725 tree simplified = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 ccp_lattice_t likelyvalue = likely_value (stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1727 bool is_constant = false;
111
kono
parents: 67
diff changeset
1728 unsigned int align;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1729
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1730 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1731 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1732 fprintf (dump_file, "which is likely ");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1733 switch (likelyvalue)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1734 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1735 case CONSTANT:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1736 fprintf (dump_file, "CONSTANT");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1737 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1738 case UNDEFINED:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1739 fprintf (dump_file, "UNDEFINED");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1740 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1741 case VARYING:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1742 fprintf (dump_file, "VARYING");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1743 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1744 default:;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1745 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1746 fprintf (dump_file, "\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1747 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 /* If the statement is likely to have a CONSTANT result, then try
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750 to fold the statement to determine the constant value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1751 /* FIXME. This is the only place that we call ccp_fold.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1752 Since likely_value never returns CONSTANT for calls, we will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1753 not attempt to fold them, including builtins that may profit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1754 if (likelyvalue == CONSTANT)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1755 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1756 fold_defer_overflow_warnings ();
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1757 simplified = ccp_fold (stmt);
111
kono
parents: 67
diff changeset
1758 if (simplified
kono
parents: 67
diff changeset
1759 && TREE_CODE (simplified) == SSA_NAME)
kono
parents: 67
diff changeset
1760 {
kono
parents: 67
diff changeset
1761 /* We may not use values of something that may be simulated again,
kono
parents: 67
diff changeset
1762 see valueize_op_1. */
kono
parents: 67
diff changeset
1763 if (SSA_NAME_IS_DEFAULT_DEF (simplified)
kono
parents: 67
diff changeset
1764 || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified)))
kono
parents: 67
diff changeset
1765 {
kono
parents: 67
diff changeset
1766 ccp_prop_value_t *val = get_value (simplified);
kono
parents: 67
diff changeset
1767 if (val && val->lattice_val != VARYING)
kono
parents: 67
diff changeset
1768 {
kono
parents: 67
diff changeset
1769 fold_undefer_overflow_warnings (true, stmt, 0);
kono
parents: 67
diff changeset
1770 return *val;
kono
parents: 67
diff changeset
1771 }
kono
parents: 67
diff changeset
1772 }
kono
parents: 67
diff changeset
1773 else
kono
parents: 67
diff changeset
1774 /* We may also not place a non-valueized copy in the lattice
kono
parents: 67
diff changeset
1775 as that might become stale if we never re-visit this stmt. */
kono
parents: 67
diff changeset
1776 simplified = NULL_TREE;
kono
parents: 67
diff changeset
1777 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1778 is_constant = simplified && is_gimple_min_invariant (simplified);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1779 fold_undefer_overflow_warnings (is_constant, stmt, 0);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1780 if (is_constant)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1781 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1782 /* The statement produced a constant value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1783 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1784 val.value = simplified;
111
kono
parents: 67
diff changeset
1785 val.mask = 0;
kono
parents: 67
diff changeset
1786 return val;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1787 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1788 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1789 /* If the statement is likely to have a VARYING result, then do not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1790 bother folding the statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1791 else if (likelyvalue == VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1792 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1793 enum gimple_code code = gimple_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1794 if (code == GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1795 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1796 enum tree_code subcode = gimple_assign_rhs_code (stmt);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1797
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1798 /* Other cases cannot satisfy is_gimple_min_invariant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1799 without folding. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1800 if (get_gimple_rhs_class (subcode) == GIMPLE_SINGLE_RHS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1801 simplified = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1802 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 else if (code == GIMPLE_SWITCH)
111
kono
parents: 67
diff changeset
1804 simplified = gimple_switch_index (as_a <gswitch *> (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 else
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1806 /* These cannot satisfy is_gimple_min_invariant without folding. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1807 gcc_assert (code == GIMPLE_CALL || code == GIMPLE_COND);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1808 is_constant = simplified && is_gimple_min_invariant (simplified);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1809 if (is_constant)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1810 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1811 /* The statement produced a constant value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1812 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1813 val.value = simplified;
111
kono
parents: 67
diff changeset
1814 val.mask = 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1815 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1816 }
111
kono
parents: 67
diff changeset
1817 /* If the statement result is likely UNDEFINED, make it so. */
kono
parents: 67
diff changeset
1818 else if (likelyvalue == UNDEFINED)
kono
parents: 67
diff changeset
1819 {
kono
parents: 67
diff changeset
1820 val.lattice_val = UNDEFINED;
kono
parents: 67
diff changeset
1821 val.value = NULL_TREE;
kono
parents: 67
diff changeset
1822 val.mask = 0;
kono
parents: 67
diff changeset
1823 return val;
kono
parents: 67
diff changeset
1824 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1826 /* Resort to simplification for bitwise tracking. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1827 if (flag_tree_bit_ccp
111
kono
parents: 67
diff changeset
1828 && (likelyvalue == CONSTANT || is_gimple_call (stmt)
kono
parents: 67
diff changeset
1829 || (gimple_assign_single_p (stmt)
kono
parents: 67
diff changeset
1830 && gimple_assign_rhs_code (stmt) == ADDR_EXPR))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1831 && !is_constant)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1832 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1833 enum gimple_code code = gimple_code (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1834 val.lattice_val = VARYING;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1835 val.value = NULL_TREE;
111
kono
parents: 67
diff changeset
1836 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1837 if (code == GIMPLE_ASSIGN)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1838 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1839 enum tree_code subcode = gimple_assign_rhs_code (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1840 tree rhs1 = gimple_assign_rhs1 (stmt);
111
kono
parents: 67
diff changeset
1841 tree lhs = gimple_assign_lhs (stmt);
kono
parents: 67
diff changeset
1842 if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
kono
parents: 67
diff changeset
1843 || POINTER_TYPE_P (TREE_TYPE (lhs)))
kono
parents: 67
diff changeset
1844 && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
kono
parents: 67
diff changeset
1845 || POINTER_TYPE_P (TREE_TYPE (rhs1))))
kono
parents: 67
diff changeset
1846 switch (get_gimple_rhs_class (subcode))
kono
parents: 67
diff changeset
1847 {
kono
parents: 67
diff changeset
1848 case GIMPLE_SINGLE_RHS:
kono
parents: 67
diff changeset
1849 val = get_value_for_expr (rhs1, true);
kono
parents: 67
diff changeset
1850 break;
kono
parents: 67
diff changeset
1851
kono
parents: 67
diff changeset
1852 case GIMPLE_UNARY_RHS:
kono
parents: 67
diff changeset
1853 val = bit_value_unop (subcode, TREE_TYPE (lhs), rhs1);
kono
parents: 67
diff changeset
1854 break;
kono
parents: 67
diff changeset
1855
kono
parents: 67
diff changeset
1856 case GIMPLE_BINARY_RHS:
kono
parents: 67
diff changeset
1857 val = bit_value_binop (subcode, TREE_TYPE (lhs), rhs1,
kono
parents: 67
diff changeset
1858 gimple_assign_rhs2 (stmt));
kono
parents: 67
diff changeset
1859 break;
kono
parents: 67
diff changeset
1860
kono
parents: 67
diff changeset
1861 default:;
kono
parents: 67
diff changeset
1862 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1863 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1864 else if (code == GIMPLE_COND)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1865 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1866 enum tree_code code = gimple_cond_code (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1867 tree rhs1 = gimple_cond_lhs (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1868 tree rhs2 = gimple_cond_rhs (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1869 if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1870 || POINTER_TYPE_P (TREE_TYPE (rhs1)))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1871 val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1872 }
111
kono
parents: 67
diff changeset
1873 else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1874 {
111
kono
parents: 67
diff changeset
1875 tree fndecl = gimple_call_fndecl (stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1876 switch (DECL_FUNCTION_CODE (fndecl))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1877 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1878 case BUILT_IN_MALLOC:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1879 case BUILT_IN_REALLOC:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1880 case BUILT_IN_CALLOC:
111
kono
parents: 67
diff changeset
1881 case BUILT_IN_STRDUP:
kono
parents: 67
diff changeset
1882 case BUILT_IN_STRNDUP:
kono
parents: 67
diff changeset
1883 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
1884 val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
kono
parents: 67
diff changeset
1885 val.mask = ~((HOST_WIDE_INT) MALLOC_ABI_ALIGNMENT
kono
parents: 67
diff changeset
1886 / BITS_PER_UNIT - 1);
kono
parents: 67
diff changeset
1887 break;
kono
parents: 67
diff changeset
1888
kono
parents: 67
diff changeset
1889 CASE_BUILT_IN_ALLOCA:
kono
parents: 67
diff changeset
1890 align = (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA
kono
parents: 67
diff changeset
1891 ? BIGGEST_ALIGNMENT
kono
parents: 67
diff changeset
1892 : TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)));
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1893 val.lattice_val = CONSTANT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1894 val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
111
kono
parents: 67
diff changeset
1895 val.mask = ~((HOST_WIDE_INT) align / BITS_PER_UNIT - 1);
kono
parents: 67
diff changeset
1896 break;
kono
parents: 67
diff changeset
1897
kono
parents: 67
diff changeset
1898 /* These builtins return their first argument, unmodified. */
kono
parents: 67
diff changeset
1899 case BUILT_IN_MEMCPY:
kono
parents: 67
diff changeset
1900 case BUILT_IN_MEMMOVE:
kono
parents: 67
diff changeset
1901 case BUILT_IN_MEMSET:
kono
parents: 67
diff changeset
1902 case BUILT_IN_STRCPY:
kono
parents: 67
diff changeset
1903 case BUILT_IN_STRNCPY:
kono
parents: 67
diff changeset
1904 case BUILT_IN_MEMCPY_CHK:
kono
parents: 67
diff changeset
1905 case BUILT_IN_MEMMOVE_CHK:
kono
parents: 67
diff changeset
1906 case BUILT_IN_MEMSET_CHK:
kono
parents: 67
diff changeset
1907 case BUILT_IN_STRCPY_CHK:
kono
parents: 67
diff changeset
1908 case BUILT_IN_STRNCPY_CHK:
kono
parents: 67
diff changeset
1909 val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
kono
parents: 67
diff changeset
1910 break;
kono
parents: 67
diff changeset
1911
kono
parents: 67
diff changeset
1912 case BUILT_IN_ASSUME_ALIGNED:
kono
parents: 67
diff changeset
1913 val = bit_value_assume_aligned (stmt, NULL_TREE, val, false);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1914 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1915
111
kono
parents: 67
diff changeset
1916 case BUILT_IN_ALIGNED_ALLOC:
kono
parents: 67
diff changeset
1917 {
kono
parents: 67
diff changeset
1918 tree align = get_constant_value (gimple_call_arg (stmt, 0));
kono
parents: 67
diff changeset
1919 if (align
kono
parents: 67
diff changeset
1920 && tree_fits_uhwi_p (align))
kono
parents: 67
diff changeset
1921 {
kono
parents: 67
diff changeset
1922 unsigned HOST_WIDE_INT aligni = tree_to_uhwi (align);
kono
parents: 67
diff changeset
1923 if (aligni > 1
kono
parents: 67
diff changeset
1924 /* align must be power-of-two */
kono
parents: 67
diff changeset
1925 && (aligni & (aligni - 1)) == 0)
kono
parents: 67
diff changeset
1926 {
kono
parents: 67
diff changeset
1927 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
1928 val.value = build_int_cst (ptr_type_node, 0);
kono
parents: 67
diff changeset
1929 val.mask = -aligni;
kono
parents: 67
diff changeset
1930 }
kono
parents: 67
diff changeset
1931 }
kono
parents: 67
diff changeset
1932 break;
kono
parents: 67
diff changeset
1933 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1934
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1935 default:;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1936 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1937 }
111
kono
parents: 67
diff changeset
1938 if (is_gimple_call (stmt) && gimple_call_lhs (stmt))
kono
parents: 67
diff changeset
1939 {
kono
parents: 67
diff changeset
1940 tree fntype = gimple_call_fntype (stmt);
kono
parents: 67
diff changeset
1941 if (fntype)
kono
parents: 67
diff changeset
1942 {
kono
parents: 67
diff changeset
1943 tree attrs = lookup_attribute ("assume_aligned",
kono
parents: 67
diff changeset
1944 TYPE_ATTRIBUTES (fntype));
kono
parents: 67
diff changeset
1945 if (attrs)
kono
parents: 67
diff changeset
1946 val = bit_value_assume_aligned (stmt, attrs, val, false);
kono
parents: 67
diff changeset
1947 attrs = lookup_attribute ("alloc_align",
kono
parents: 67
diff changeset
1948 TYPE_ATTRIBUTES (fntype));
kono
parents: 67
diff changeset
1949 if (attrs)
kono
parents: 67
diff changeset
1950 val = bit_value_assume_aligned (stmt, attrs, val, true);
kono
parents: 67
diff changeset
1951 }
kono
parents: 67
diff changeset
1952 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1953 is_constant = (val.lattice_val == CONSTANT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1954 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1955
111
kono
parents: 67
diff changeset
1956 if (flag_tree_bit_ccp
kono
parents: 67
diff changeset
1957 && ((is_constant && TREE_CODE (val.value) == INTEGER_CST)
kono
parents: 67
diff changeset
1958 || !is_constant)
kono
parents: 67
diff changeset
1959 && gimple_get_lhs (stmt)
kono
parents: 67
diff changeset
1960 && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME)
kono
parents: 67
diff changeset
1961 {
kono
parents: 67
diff changeset
1962 tree lhs = gimple_get_lhs (stmt);
kono
parents: 67
diff changeset
1963 wide_int nonzero_bits = get_nonzero_bits (lhs);
kono
parents: 67
diff changeset
1964 if (nonzero_bits != -1)
kono
parents: 67
diff changeset
1965 {
kono
parents: 67
diff changeset
1966 if (!is_constant)
kono
parents: 67
diff changeset
1967 {
kono
parents: 67
diff changeset
1968 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
1969 val.value = build_zero_cst (TREE_TYPE (lhs));
kono
parents: 67
diff changeset
1970 val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (lhs)));
kono
parents: 67
diff changeset
1971 is_constant = true;
kono
parents: 67
diff changeset
1972 }
kono
parents: 67
diff changeset
1973 else
kono
parents: 67
diff changeset
1974 {
kono
parents: 67
diff changeset
1975 if (wi::bit_and_not (wi::to_wide (val.value), nonzero_bits) != 0)
kono
parents: 67
diff changeset
1976 val.value = wide_int_to_tree (TREE_TYPE (lhs),
kono
parents: 67
diff changeset
1977 nonzero_bits
kono
parents: 67
diff changeset
1978 & wi::to_wide (val.value));
kono
parents: 67
diff changeset
1979 if (nonzero_bits == 0)
kono
parents: 67
diff changeset
1980 val.mask = 0;
kono
parents: 67
diff changeset
1981 else
kono
parents: 67
diff changeset
1982 val.mask = val.mask & extend_mask (nonzero_bits,
kono
parents: 67
diff changeset
1983 TYPE_SIGN (TREE_TYPE (lhs)));
kono
parents: 67
diff changeset
1984 }
kono
parents: 67
diff changeset
1985 }
kono
parents: 67
diff changeset
1986 }
kono
parents: 67
diff changeset
1987
kono
parents: 67
diff changeset
1988 /* The statement produced a nonconstant value. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1989 if (!is_constant)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1990 {
111
kono
parents: 67
diff changeset
1991 /* The statement produced a copy. */
kono
parents: 67
diff changeset
1992 if (simplified && TREE_CODE (simplified) == SSA_NAME
kono
parents: 67
diff changeset
1993 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1994 {
111
kono
parents: 67
diff changeset
1995 val.lattice_val = CONSTANT;
kono
parents: 67
diff changeset
1996 val.value = simplified;
kono
parents: 67
diff changeset
1997 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1998 }
111
kono
parents: 67
diff changeset
1999 /* The statement is VARYING. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2000 else
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2001 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2002 val.lattice_val = VARYING;
111
kono
parents: 67
diff changeset
2003 val.value = NULL_TREE;
kono
parents: 67
diff changeset
2004 val.mask = -1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2005 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2006 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2007
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2008 return val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2009 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2010
111
kono
parents: 67
diff changeset
2011 typedef hash_table<nofree_ptr_hash<gimple> > gimple_htab;
kono
parents: 67
diff changeset
2012
kono
parents: 67
diff changeset
2013 /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before
kono
parents: 67
diff changeset
2014 each matching BUILT_IN_STACK_RESTORE. Mark visited phis in VISITED. */
kono
parents: 67
diff changeset
2015
kono
parents: 67
diff changeset
2016 static void
kono
parents: 67
diff changeset
2017 insert_clobber_before_stack_restore (tree saved_val, tree var,
kono
parents: 67
diff changeset
2018 gimple_htab **visited)
kono
parents: 67
diff changeset
2019 {
kono
parents: 67
diff changeset
2020 gimple *stmt;
kono
parents: 67
diff changeset
2021 gassign *clobber_stmt;
kono
parents: 67
diff changeset
2022 tree clobber;
kono
parents: 67
diff changeset
2023 imm_use_iterator iter;
kono
parents: 67
diff changeset
2024 gimple_stmt_iterator i;
kono
parents: 67
diff changeset
2025 gimple **slot;
kono
parents: 67
diff changeset
2026
kono
parents: 67
diff changeset
2027 FOR_EACH_IMM_USE_STMT (stmt, iter, saved_val)
kono
parents: 67
diff changeset
2028 if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
kono
parents: 67
diff changeset
2029 {
kono
parents: 67
diff changeset
2030 clobber = build_constructor (TREE_TYPE (var),
kono
parents: 67
diff changeset
2031 NULL);
kono
parents: 67
diff changeset
2032 TREE_THIS_VOLATILE (clobber) = 1;
kono
parents: 67
diff changeset
2033 clobber_stmt = gimple_build_assign (var, clobber);
kono
parents: 67
diff changeset
2034
kono
parents: 67
diff changeset
2035 i = gsi_for_stmt (stmt);
kono
parents: 67
diff changeset
2036 gsi_insert_before (&i, clobber_stmt, GSI_SAME_STMT);
kono
parents: 67
diff changeset
2037 }
kono
parents: 67
diff changeset
2038 else if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
2039 {
kono
parents: 67
diff changeset
2040 if (!*visited)
kono
parents: 67
diff changeset
2041 *visited = new gimple_htab (10);
kono
parents: 67
diff changeset
2042
kono
parents: 67
diff changeset
2043 slot = (*visited)->find_slot (stmt, INSERT);
kono
parents: 67
diff changeset
2044 if (*slot != NULL)
kono
parents: 67
diff changeset
2045 continue;
kono
parents: 67
diff changeset
2046
kono
parents: 67
diff changeset
2047 *slot = stmt;
kono
parents: 67
diff changeset
2048 insert_clobber_before_stack_restore (gimple_phi_result (stmt), var,
kono
parents: 67
diff changeset
2049 visited);
kono
parents: 67
diff changeset
2050 }
kono
parents: 67
diff changeset
2051 else if (gimple_assign_ssa_name_copy_p (stmt))
kono
parents: 67
diff changeset
2052 insert_clobber_before_stack_restore (gimple_assign_lhs (stmt), var,
kono
parents: 67
diff changeset
2053 visited);
kono
parents: 67
diff changeset
2054 else if (chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDRET))
kono
parents: 67
diff changeset
2055 continue;
kono
parents: 67
diff changeset
2056 else
kono
parents: 67
diff changeset
2057 gcc_assert (is_gimple_debug (stmt));
kono
parents: 67
diff changeset
2058 }
kono
parents: 67
diff changeset
2059
kono
parents: 67
diff changeset
2060 /* Advance the iterator to the previous non-debug gimple statement in the same
kono
parents: 67
diff changeset
2061 or dominating basic block. */
kono
parents: 67
diff changeset
2062
kono
parents: 67
diff changeset
2063 static inline void
kono
parents: 67
diff changeset
2064 gsi_prev_dom_bb_nondebug (gimple_stmt_iterator *i)
kono
parents: 67
diff changeset
2065 {
kono
parents: 67
diff changeset
2066 basic_block dom;
kono
parents: 67
diff changeset
2067
kono
parents: 67
diff changeset
2068 gsi_prev_nondebug (i);
kono
parents: 67
diff changeset
2069 while (gsi_end_p (*i))
kono
parents: 67
diff changeset
2070 {
kono
parents: 67
diff changeset
2071 dom = get_immediate_dominator (CDI_DOMINATORS, i->bb);
kono
parents: 67
diff changeset
2072 if (dom == NULL || dom == ENTRY_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
2073 return;
kono
parents: 67
diff changeset
2074
kono
parents: 67
diff changeset
2075 *i = gsi_last_bb (dom);
kono
parents: 67
diff changeset
2076 }
kono
parents: 67
diff changeset
2077 }
kono
parents: 67
diff changeset
2078
kono
parents: 67
diff changeset
2079 /* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert
kono
parents: 67
diff changeset
2080 a clobber of VAR before each matching BUILT_IN_STACK_RESTORE.
kono
parents: 67
diff changeset
2081
kono
parents: 67
diff changeset
2082 It is possible that BUILT_IN_STACK_SAVE cannot be find in a dominator when a
kono
parents: 67
diff changeset
2083 previous pass (such as DOM) duplicated it along multiple paths to a BB. In
kono
parents: 67
diff changeset
2084 that case the function gives up without inserting the clobbers. */
kono
parents: 67
diff changeset
2085
kono
parents: 67
diff changeset
2086 static void
kono
parents: 67
diff changeset
2087 insert_clobbers_for_var (gimple_stmt_iterator i, tree var)
kono
parents: 67
diff changeset
2088 {
kono
parents: 67
diff changeset
2089 gimple *stmt;
kono
parents: 67
diff changeset
2090 tree saved_val;
kono
parents: 67
diff changeset
2091 gimple_htab *visited = NULL;
kono
parents: 67
diff changeset
2092
kono
parents: 67
diff changeset
2093 for (; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i))
kono
parents: 67
diff changeset
2094 {
kono
parents: 67
diff changeset
2095 stmt = gsi_stmt (i);
kono
parents: 67
diff changeset
2096
kono
parents: 67
diff changeset
2097 if (!gimple_call_builtin_p (stmt, BUILT_IN_STACK_SAVE))
kono
parents: 67
diff changeset
2098 continue;
kono
parents: 67
diff changeset
2099
kono
parents: 67
diff changeset
2100 saved_val = gimple_call_lhs (stmt);
kono
parents: 67
diff changeset
2101 if (saved_val == NULL_TREE)
kono
parents: 67
diff changeset
2102 continue;
kono
parents: 67
diff changeset
2103
kono
parents: 67
diff changeset
2104 insert_clobber_before_stack_restore (saved_val, var, &visited);
kono
parents: 67
diff changeset
2105 break;
kono
parents: 67
diff changeset
2106 }
kono
parents: 67
diff changeset
2107
kono
parents: 67
diff changeset
2108 delete visited;
kono
parents: 67
diff changeset
2109 }
kono
parents: 67
diff changeset
2110
kono
parents: 67
diff changeset
2111 /* Detects a __builtin_alloca_with_align with constant size argument. Declares
kono
parents: 67
diff changeset
2112 fixed-size array and returns the address, if found, otherwise returns
kono
parents: 67
diff changeset
2113 NULL_TREE. */
kono
parents: 67
diff changeset
2114
kono
parents: 67
diff changeset
2115 static tree
kono
parents: 67
diff changeset
2116 fold_builtin_alloca_with_align (gimple *stmt)
kono
parents: 67
diff changeset
2117 {
kono
parents: 67
diff changeset
2118 unsigned HOST_WIDE_INT size, threshold, n_elem;
kono
parents: 67
diff changeset
2119 tree lhs, arg, block, var, elem_type, array_type;
kono
parents: 67
diff changeset
2120
kono
parents: 67
diff changeset
2121 /* Get lhs. */
kono
parents: 67
diff changeset
2122 lhs = gimple_call_lhs (stmt);
kono
parents: 67
diff changeset
2123 if (lhs == NULL_TREE)
kono
parents: 67
diff changeset
2124 return NULL_TREE;
kono
parents: 67
diff changeset
2125
kono
parents: 67
diff changeset
2126 /* Detect constant argument. */
kono
parents: 67
diff changeset
2127 arg = get_constant_value (gimple_call_arg (stmt, 0));
kono
parents: 67
diff changeset
2128 if (arg == NULL_TREE
kono
parents: 67
diff changeset
2129 || TREE_CODE (arg) != INTEGER_CST
kono
parents: 67
diff changeset
2130 || !tree_fits_uhwi_p (arg))
kono
parents: 67
diff changeset
2131 return NULL_TREE;
kono
parents: 67
diff changeset
2132
kono
parents: 67
diff changeset
2133 size = tree_to_uhwi (arg);
kono
parents: 67
diff changeset
2134
kono
parents: 67
diff changeset
2135 /* Heuristic: don't fold large allocas. */
kono
parents: 67
diff changeset
2136 threshold = (unsigned HOST_WIDE_INT)PARAM_VALUE (PARAM_LARGE_STACK_FRAME);
kono
parents: 67
diff changeset
2137 /* In case the alloca is located at function entry, it has the same lifetime
kono
parents: 67
diff changeset
2138 as a declared array, so we allow a larger size. */
kono
parents: 67
diff changeset
2139 block = gimple_block (stmt);
kono
parents: 67
diff changeset
2140 if (!(cfun->after_inlining
kono
parents: 67
diff changeset
2141 && block
kono
parents: 67
diff changeset
2142 && TREE_CODE (BLOCK_SUPERCONTEXT (block)) == FUNCTION_DECL))
kono
parents: 67
diff changeset
2143 threshold /= 10;
kono
parents: 67
diff changeset
2144 if (size > threshold)
kono
parents: 67
diff changeset
2145 return NULL_TREE;
kono
parents: 67
diff changeset
2146
kono
parents: 67
diff changeset
2147 /* Declare array. */
kono
parents: 67
diff changeset
2148 elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1);
kono
parents: 67
diff changeset
2149 n_elem = size * 8 / BITS_PER_UNIT;
kono
parents: 67
diff changeset
2150 array_type = build_array_type_nelts (elem_type, n_elem);
kono
parents: 67
diff changeset
2151 var = create_tmp_var (array_type);
kono
parents: 67
diff changeset
2152 SET_DECL_ALIGN (var, TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)));
kono
parents: 67
diff changeset
2153 {
kono
parents: 67
diff changeset
2154 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
kono
parents: 67
diff changeset
2155 if (pi != NULL && !pi->pt.anything)
kono
parents: 67
diff changeset
2156 {
kono
parents: 67
diff changeset
2157 bool singleton_p;
kono
parents: 67
diff changeset
2158 unsigned uid;
kono
parents: 67
diff changeset
2159 singleton_p = pt_solution_singleton_or_null_p (&pi->pt, &uid);
kono
parents: 67
diff changeset
2160 gcc_assert (singleton_p);
kono
parents: 67
diff changeset
2161 SET_DECL_PT_UID (var, uid);
kono
parents: 67
diff changeset
2162 }
kono
parents: 67
diff changeset
2163 }
kono
parents: 67
diff changeset
2164
kono
parents: 67
diff changeset
2165 /* Fold alloca to the address of the array. */
kono
parents: 67
diff changeset
2166 return fold_convert (TREE_TYPE (lhs), build_fold_addr_expr (var));
kono
parents: 67
diff changeset
2167 }
kono
parents: 67
diff changeset
2168
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2169 /* Fold the stmt at *GSI with CCP specific information that propagating
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2170 and regular folding does not catch. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2171
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2172 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2173 ccp_fold_stmt (gimple_stmt_iterator *gsi)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2174 {
111
kono
parents: 67
diff changeset
2175 gimple *stmt = gsi_stmt (*gsi);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2176
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2177 switch (gimple_code (stmt))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2178 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2179 case GIMPLE_COND:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2180 {
111
kono
parents: 67
diff changeset
2181 gcond *cond_stmt = as_a <gcond *> (stmt);
kono
parents: 67
diff changeset
2182 ccp_prop_value_t val;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2183 /* Statement evaluation will handle type mismatches in constants
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2184 more gracefully than the final propagation. This allows us to
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2185 fold more conditionals here. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2186 val = evaluate_stmt (stmt);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2187 if (val.lattice_val != CONSTANT
111
kono
parents: 67
diff changeset
2188 || val.mask != 0)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2189 return false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2190
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2191 if (dump_file)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2192 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2193 fprintf (dump_file, "Folding predicate ");
111
kono
parents: 67
diff changeset
2194 print_gimple_expr (dump_file, stmt, 0);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2195 fprintf (dump_file, " to ");
111
kono
parents: 67
diff changeset
2196 print_generic_expr (dump_file, val.value);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2197 fprintf (dump_file, "\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2198 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2199
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2200 if (integer_zerop (val.value))
111
kono
parents: 67
diff changeset
2201 gimple_cond_make_false (cond_stmt);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2202 else
111
kono
parents: 67
diff changeset
2203 gimple_cond_make_true (cond_stmt);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2204
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2205 return true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2206 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2207
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2208 case GIMPLE_CALL:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2209 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2210 tree lhs = gimple_call_lhs (stmt);
111
kono
parents: 67
diff changeset
2211 int flags = gimple_call_flags (stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2212 tree val;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2213 tree argt;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2214 bool changed = false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2215 unsigned i;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2216
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2217 /* If the call was folded into a constant make sure it goes
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2218 away even if we cannot propagate into all uses because of
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2219 type issues. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2220 if (lhs
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2221 && TREE_CODE (lhs) == SSA_NAME
111
kono
parents: 67
diff changeset
2222 && (val = get_constant_value (lhs))
kono
parents: 67
diff changeset
2223 /* Don't optimize away calls that have side-effects. */
kono
parents: 67
diff changeset
2224 && (flags & (ECF_CONST|ECF_PURE)) != 0
kono
parents: 67
diff changeset
2225 && (flags & ECF_LOOPING_CONST_OR_PURE) == 0)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2226 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2227 tree new_rhs = unshare_expr (val);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2228 bool res;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2229 if (!useless_type_conversion_p (TREE_TYPE (lhs),
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2230 TREE_TYPE (new_rhs)))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2231 new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2232 res = update_call_from_tree (gsi, new_rhs);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2233 gcc_assert (res);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2234 return true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2235 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2236
111
kono
parents: 67
diff changeset
2237 /* Internal calls provide no argument types, so the extra laxity
kono
parents: 67
diff changeset
2238 for normal calls does not apply. */
kono
parents: 67
diff changeset
2239 if (gimple_call_internal_p (stmt))
kono
parents: 67
diff changeset
2240 return false;
kono
parents: 67
diff changeset
2241
kono
parents: 67
diff changeset
2242 /* The heuristic of fold_builtin_alloca_with_align differs before and
kono
parents: 67
diff changeset
2243 after inlining, so we don't require the arg to be changed into a
kono
parents: 67
diff changeset
2244 constant for folding, but just to be constant. */
kono
parents: 67
diff changeset
2245 if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN)
kono
parents: 67
diff changeset
2246 || gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX))
kono
parents: 67
diff changeset
2247 {
kono
parents: 67
diff changeset
2248 tree new_rhs = fold_builtin_alloca_with_align (stmt);
kono
parents: 67
diff changeset
2249 if (new_rhs)
kono
parents: 67
diff changeset
2250 {
kono
parents: 67
diff changeset
2251 bool res = update_call_from_tree (gsi, new_rhs);
kono
parents: 67
diff changeset
2252 tree var = TREE_OPERAND (TREE_OPERAND (new_rhs, 0),0);
kono
parents: 67
diff changeset
2253 gcc_assert (res);
kono
parents: 67
diff changeset
2254 insert_clobbers_for_var (*gsi, var);
kono
parents: 67
diff changeset
2255 return true;
kono
parents: 67
diff changeset
2256 }
kono
parents: 67
diff changeset
2257 }
kono
parents: 67
diff changeset
2258
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2259 /* Propagate into the call arguments. Compared to replace_uses_in
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2260 this can use the argument slot types for type verification
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2261 instead of the current argument type. We also can safely
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2262 drop qualifiers here as we are dealing with constants anyway. */
111
kono
parents: 67
diff changeset
2263 argt = TYPE_ARG_TYPES (gimple_call_fntype (stmt));
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2264 for (i = 0; i < gimple_call_num_args (stmt) && argt;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2265 ++i, argt = TREE_CHAIN (argt))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2266 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2267 tree arg = gimple_call_arg (stmt, i);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2268 if (TREE_CODE (arg) == SSA_NAME
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2269 && (val = get_constant_value (arg))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2270 && useless_type_conversion_p
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2271 (TYPE_MAIN_VARIANT (TREE_VALUE (argt)),
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2272 TYPE_MAIN_VARIANT (TREE_TYPE (val))))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2273 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2274 gimple_call_set_arg (stmt, i, unshare_expr (val));
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2275 changed = true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2276 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2277 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2278
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2279 return changed;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2280 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2281
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2282 case GIMPLE_ASSIGN:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2283 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2284 tree lhs = gimple_assign_lhs (stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2285 tree val;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2286
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2287 /* If we have a load that turned out to be constant replace it
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2288 as we cannot propagate into all uses in all cases. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2289 if (gimple_assign_single_p (stmt)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2290 && TREE_CODE (lhs) == SSA_NAME
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2291 && (val = get_constant_value (lhs)))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2292 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2293 tree rhs = unshare_expr (val);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2294 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2295 rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2296 gimple_assign_set_rhs_from_tree (gsi, rhs);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2297 return true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2298 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2299
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2300 return false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2301 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2302
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2303 default:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2304 return false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2305 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2306 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2307
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2308 /* Visit the assignment statement STMT. Set the value of its LHS to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2309 value computed by the RHS and store LHS in *OUTPUT_P. If STMT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2310 creates virtual definitions, set the value of each new name to that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2311 of the RHS (if we can derive a constant out of the RHS).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2312 Value-returning call statements also perform an assignment, and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2313 are handled here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2315 static enum ssa_prop_result
111
kono
parents: 67
diff changeset
2316 visit_assignment (gimple *stmt, tree *output_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2317 {
111
kono
parents: 67
diff changeset
2318 ccp_prop_value_t val;
kono
parents: 67
diff changeset
2319 enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2321 tree lhs = gimple_get_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2322 if (TREE_CODE (lhs) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2323 {
111
kono
parents: 67
diff changeset
2324 /* Evaluate the statement, which could be
kono
parents: 67
diff changeset
2325 either a GIMPLE_ASSIGN or a GIMPLE_CALL. */
kono
parents: 67
diff changeset
2326 val = evaluate_stmt (stmt);
kono
parents: 67
diff changeset
2327
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2328 /* If STMT is an assignment to an SSA_NAME, we only have one
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2329 value to set. */
111
kono
parents: 67
diff changeset
2330 if (set_lattice_value (lhs, &val))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2331 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2332 *output_p = lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2333 if (val.lattice_val == VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2334 retval = SSA_PROP_VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2335 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2336 retval = SSA_PROP_INTERESTING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2337 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2338 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2339
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2340 return retval;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2341 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2342
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2344 /* Visit the conditional statement STMT. Return SSA_PROP_INTERESTING
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2345 if it can determine which edge will be taken. Otherwise, return
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2346 SSA_PROP_VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2347
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2348 static enum ssa_prop_result
111
kono
parents: 67
diff changeset
2349 visit_cond_stmt (gimple *stmt, edge *taken_edge_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2350 {
111
kono
parents: 67
diff changeset
2351 ccp_prop_value_t val;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2352 basic_block block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2353
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2354 block = gimple_bb (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2355 val = evaluate_stmt (stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2356 if (val.lattice_val != CONSTANT
111
kono
parents: 67
diff changeset
2357 || val.mask != 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2358 return SSA_PROP_VARYING;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2359
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2360 /* Find which edge out of the conditional block will be taken and add it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2361 to the worklist. If no single edge can be determined statically,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2362 return SSA_PROP_VARYING to feed all the outgoing edges to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2363 propagation engine. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2364 *taken_edge_p = find_taken_edge (block, val.value);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2365 if (*taken_edge_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2366 return SSA_PROP_INTERESTING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2367 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2368 return SSA_PROP_VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2369 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2370
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2372 /* Evaluate statement STMT. If the statement produces an output value and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2373 its evaluation changes the lattice value of its output, return
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2374 SSA_PROP_INTERESTING and set *OUTPUT_P to the SSA_NAME holding the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2375 output value.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2376
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2377 If STMT is a conditional branch and we can determine its truth
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2378 value, set *TAKEN_EDGE_P accordingly. If STMT produces a varying
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2379 value, return SSA_PROP_VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2380
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2381 static enum ssa_prop_result
111
kono
parents: 67
diff changeset
2382 ccp_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2383 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2384 tree def;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2385 ssa_op_iter iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2386
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2387 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2388 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2389 fprintf (dump_file, "\nVisiting statement:\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2390 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2391 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2392
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2393 switch (gimple_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2394 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2395 case GIMPLE_ASSIGN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2396 /* If the statement is an assignment that produces a single
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2397 output value, evaluate its RHS to see if the lattice value of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2398 its output has changed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2399 return visit_assignment (stmt, output_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2400
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2401 case GIMPLE_CALL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2402 /* A value-returning call also performs an assignment. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2403 if (gimple_call_lhs (stmt) != NULL_TREE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2404 return visit_assignment (stmt, output_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2405 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2407 case GIMPLE_COND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2408 case GIMPLE_SWITCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2409 /* If STMT is a conditional branch, see if we can determine
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2410 which branch will be taken. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2411 /* FIXME. It appears that we should be able to optimize
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2412 computed GOTOs here as well. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2413 return visit_cond_stmt (stmt, taken_edge_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2414
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2415 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2416 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2417 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2418
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2419 /* Any other kind of statement is not interesting for constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2420 propagation and, therefore, not worth simulating. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2421 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2422 fprintf (dump_file, "No interesting values produced. Marked VARYING.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2423
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2424 /* Definitions made by statements other than assignments to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2425 SSA_NAMEs represent unknown modifications to their outputs.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2426 Mark them VARYING. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2427 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
111
kono
parents: 67
diff changeset
2428 set_value_varying (def);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2429
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2430 return SSA_PROP_VARYING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2431 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2432
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2433
111
kono
parents: 67
diff changeset
2434 /* Main entry point for SSA Conditional Constant Propagation. If NONZERO_P,
kono
parents: 67
diff changeset
2435 record nonzero bits. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2436
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2437 static unsigned int
111
kono
parents: 67
diff changeset
2438 do_ssa_ccp (bool nonzero_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2439 {
111
kono
parents: 67
diff changeset
2440 unsigned int todo = 0;
kono
parents: 67
diff changeset
2441 calculate_dominance_info (CDI_DOMINATORS);
kono
parents: 67
diff changeset
2442
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2443 ccp_initialize ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2444 ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node);
111
kono
parents: 67
diff changeset
2445 if (ccp_finalize (nonzero_p || flag_ipa_bit_cp))
kono
parents: 67
diff changeset
2446 {
kono
parents: 67
diff changeset
2447 todo = (TODO_cleanup_cfg | TODO_update_ssa);
kono
parents: 67
diff changeset
2448
kono
parents: 67
diff changeset
2449 /* ccp_finalize does not preserve loop-closed ssa. */
kono
parents: 67
diff changeset
2450 loops_state_clear (LOOP_CLOSED_SSA);
kono
parents: 67
diff changeset
2451 }
kono
parents: 67
diff changeset
2452
kono
parents: 67
diff changeset
2453 free_dominance_info (CDI_DOMINATORS);
kono
parents: 67
diff changeset
2454 return todo;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2455 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2457
111
kono
parents: 67
diff changeset
2458 namespace {
kono
parents: 67
diff changeset
2459
kono
parents: 67
diff changeset
2460 const pass_data pass_data_ccp =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2461 {
111
kono
parents: 67
diff changeset
2462 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
2463 "ccp", /* name */
kono
parents: 67
diff changeset
2464 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
2465 TV_TREE_CCP, /* tv_id */
kono
parents: 67
diff changeset
2466 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
2467 0, /* properties_provided */
kono
parents: 67
diff changeset
2468 0, /* properties_destroyed */
kono
parents: 67
diff changeset
2469 0, /* todo_flags_start */
kono
parents: 67
diff changeset
2470 TODO_update_address_taken, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2471 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2472
111
kono
parents: 67
diff changeset
2473 class pass_ccp : public gimple_opt_pass
kono
parents: 67
diff changeset
2474 {
kono
parents: 67
diff changeset
2475 public:
kono
parents: 67
diff changeset
2476 pass_ccp (gcc::context *ctxt)
kono
parents: 67
diff changeset
2477 : gimple_opt_pass (pass_data_ccp, ctxt), nonzero_p (false)
kono
parents: 67
diff changeset
2478 {}
kono
parents: 67
diff changeset
2479
kono
parents: 67
diff changeset
2480 /* opt_pass methods: */
kono
parents: 67
diff changeset
2481 opt_pass * clone () { return new pass_ccp (m_ctxt); }
kono
parents: 67
diff changeset
2482 void set_pass_param (unsigned int n, bool param)
kono
parents: 67
diff changeset
2483 {
kono
parents: 67
diff changeset
2484 gcc_assert (n == 0);
kono
parents: 67
diff changeset
2485 nonzero_p = param;
kono
parents: 67
diff changeset
2486 }
kono
parents: 67
diff changeset
2487 virtual bool gate (function *) { return flag_tree_ccp != 0; }
kono
parents: 67
diff changeset
2488 virtual unsigned int execute (function *) { return do_ssa_ccp (nonzero_p); }
kono
parents: 67
diff changeset
2489
kono
parents: 67
diff changeset
2490 private:
kono
parents: 67
diff changeset
2491 /* Determines whether the pass instance records nonzero bits. */
kono
parents: 67
diff changeset
2492 bool nonzero_p;
kono
parents: 67
diff changeset
2493 }; // class pass_ccp
kono
parents: 67
diff changeset
2494
kono
parents: 67
diff changeset
2495 } // anon namespace
kono
parents: 67
diff changeset
2496
kono
parents: 67
diff changeset
2497 gimple_opt_pass *
kono
parents: 67
diff changeset
2498 make_pass_ccp (gcc::context *ctxt)
kono
parents: 67
diff changeset
2499 {
kono
parents: 67
diff changeset
2500 return new pass_ccp (ctxt);
kono
parents: 67
diff changeset
2501 }
kono
parents: 67
diff changeset
2502
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2503
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2504
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2505 /* Try to optimize out __builtin_stack_restore. Optimize it out
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2506 if there is another __builtin_stack_restore in the same basic
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2507 block and no calls or ASM_EXPRs are in between, or if this block's
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2508 only outgoing edge is to EXIT_BLOCK and there are no calls or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2509 ASM_EXPRs after this __builtin_stack_restore. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2510
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2511 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2512 optimize_stack_restore (gimple_stmt_iterator i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2513 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2514 tree callee;
111
kono
parents: 67
diff changeset
2515 gimple *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2516
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517 basic_block bb = gsi_bb (i);
111
kono
parents: 67
diff changeset
2518 gimple *call = gsi_stmt (i);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2519
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2520 if (gimple_code (call) != GIMPLE_CALL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2521 || gimple_call_num_args (call) != 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2522 || TREE_CODE (gimple_call_arg (call, 0)) != SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2523 || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2524 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2525
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2526 for (gsi_next (&i); !gsi_end_p (i); gsi_next (&i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2527 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2528 stmt = gsi_stmt (i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2529 if (gimple_code (stmt) == GIMPLE_ASM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2530 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2531 if (gimple_code (stmt) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2532 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2533
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2534 callee = gimple_call_fndecl (stmt);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2535 if (!callee
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2536 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2537 /* All regular builtins are ok, just obviously not alloca. */
111
kono
parents: 67
diff changeset
2538 || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2539 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2540
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2541 if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2542 goto second_stack_restore;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2543 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2544
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2545 if (!gsi_end_p (i))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2546 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2547
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2548 /* Allow one successor of the exit block, or zero successors. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2549 switch (EDGE_COUNT (bb->succs))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2550 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2551 case 0:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2552 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2553 case 1:
111
kono
parents: 67
diff changeset
2554 if (single_succ_edge (bb)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2555 return NULL_TREE;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2556 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2557 default:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2558 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2559 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2560 second_stack_restore:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2561
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2562 /* If there's exactly one use, then zap the call to __builtin_stack_save.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2563 If there are multiple uses, then the last one should remove the call.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2564 In any case, whether the call to __builtin_stack_save can be removed
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2565 or not is irrelevant to removing the call to __builtin_stack_restore. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2566 if (has_single_use (gimple_call_arg (call, 0)))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2567 {
111
kono
parents: 67
diff changeset
2568 gimple *stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0));
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2569 if (is_gimple_call (stack_save))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2570 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2571 callee = gimple_call_fndecl (stack_save);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2572 if (callee
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2573 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2574 && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2575 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2576 gimple_stmt_iterator stack_save_gsi;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2577 tree rhs;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2578
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2579 stack_save_gsi = gsi_for_stmt (stack_save);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2580 rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2581 update_call_from_tree (&stack_save_gsi, rhs);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2582 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2583 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2584 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2585
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2586 /* No effect, so the statement will be deleted. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2587 return integer_zero_node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2588 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2589
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2590 /* If va_list type is a simple pointer and nothing special is needed,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2591 optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2592 __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2593 pointer assignment. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2594
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2595 static tree
111
kono
parents: 67
diff changeset
2596 optimize_stdarg_builtin (gimple *call)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2597 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2598 tree callee, lhs, rhs, cfun_va_list;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2599 bool va_list_simple_ptr;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2600 location_t loc = gimple_location (call);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2601
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2602 if (gimple_code (call) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2603 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2604
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2605 callee = gimple_call_fndecl (call);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2606
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2607 cfun_va_list = targetm.fn_abi_va_list (callee);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2608 va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2609 && (TREE_TYPE (cfun_va_list) == void_type_node
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2610 || TREE_TYPE (cfun_va_list) == char_type_node);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2611
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2612 switch (DECL_FUNCTION_CODE (callee))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2613 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2614 case BUILT_IN_VA_START:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2615 if (!va_list_simple_ptr
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2616 || targetm.expand_builtin_va_start != NULL
111
kono
parents: 67
diff changeset
2617 || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2618 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2619
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2620 if (gimple_call_num_args (call) != 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2621 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2622
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2623 lhs = gimple_call_arg (call, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2624 if (!POINTER_TYPE_P (TREE_TYPE (lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2625 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2626 != TYPE_MAIN_VARIANT (cfun_va_list))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2627 return NULL_TREE;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2628
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2629 lhs = build_fold_indirect_ref_loc (loc, lhs);
111
kono
parents: 67
diff changeset
2630 rhs = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_NEXT_ARG),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2631 1, integer_zero_node);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2632 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2633 return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2634
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2635 case BUILT_IN_VA_COPY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2636 if (!va_list_simple_ptr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2637 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2638
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2639 if (gimple_call_num_args (call) != 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2640 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2641
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2642 lhs = gimple_call_arg (call, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2643 if (!POINTER_TYPE_P (TREE_TYPE (lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2644 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2645 != TYPE_MAIN_VARIANT (cfun_va_list))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2646 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2647
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2648 lhs = build_fold_indirect_ref_loc (loc, lhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2649 rhs = gimple_call_arg (call, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2650 if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2651 != TYPE_MAIN_VARIANT (cfun_va_list))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2652 return NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2653
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2654 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2655 return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2656
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2657 case BUILT_IN_VA_END:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2658 /* No effect, so the statement will be deleted. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2659 return integer_zero_node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2660
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2661 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2662 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2663 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2664 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2665
111
kono
parents: 67
diff changeset
2666 /* Attemp to make the block of __builtin_unreachable I unreachable by changing
kono
parents: 67
diff changeset
2667 the incoming jumps. Return true if at least one jump was changed. */
kono
parents: 67
diff changeset
2668
kono
parents: 67
diff changeset
2669 static bool
kono
parents: 67
diff changeset
2670 optimize_unreachable (gimple_stmt_iterator i)
kono
parents: 67
diff changeset
2671 {
kono
parents: 67
diff changeset
2672 basic_block bb = gsi_bb (i);
kono
parents: 67
diff changeset
2673 gimple_stmt_iterator gsi;
kono
parents: 67
diff changeset
2674 gimple *stmt;
kono
parents: 67
diff changeset
2675 edge_iterator ei;
kono
parents: 67
diff changeset
2676 edge e;
kono
parents: 67
diff changeset
2677 bool ret;
kono
parents: 67
diff changeset
2678
kono
parents: 67
diff changeset
2679 if (flag_sanitize & SANITIZE_UNREACHABLE)
kono
parents: 67
diff changeset
2680 return false;
kono
parents: 67
diff changeset
2681
kono
parents: 67
diff changeset
2682 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
kono
parents: 67
diff changeset
2683 {
kono
parents: 67
diff changeset
2684 stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
2685
kono
parents: 67
diff changeset
2686 if (is_gimple_debug (stmt))
kono
parents: 67
diff changeset
2687 continue;
kono
parents: 67
diff changeset
2688
kono
parents: 67
diff changeset
2689 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
kono
parents: 67
diff changeset
2690 {
kono
parents: 67
diff changeset
2691 /* Verify we do not need to preserve the label. */
kono
parents: 67
diff changeset
2692 if (FORCED_LABEL (gimple_label_label (label_stmt)))
kono
parents: 67
diff changeset
2693 return false;
kono
parents: 67
diff changeset
2694
kono
parents: 67
diff changeset
2695 continue;
kono
parents: 67
diff changeset
2696 }
kono
parents: 67
diff changeset
2697
kono
parents: 67
diff changeset
2698 /* Only handle the case that __builtin_unreachable is the first statement
kono
parents: 67
diff changeset
2699 in the block. We rely on DCE to remove stmts without side-effects
kono
parents: 67
diff changeset
2700 before __builtin_unreachable. */
kono
parents: 67
diff changeset
2701 if (gsi_stmt (gsi) != gsi_stmt (i))
kono
parents: 67
diff changeset
2702 return false;
kono
parents: 67
diff changeset
2703 }
kono
parents: 67
diff changeset
2704
kono
parents: 67
diff changeset
2705 ret = false;
kono
parents: 67
diff changeset
2706 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents: 67
diff changeset
2707 {
kono
parents: 67
diff changeset
2708 gsi = gsi_last_bb (e->src);
kono
parents: 67
diff changeset
2709 if (gsi_end_p (gsi))
kono
parents: 67
diff changeset
2710 continue;
kono
parents: 67
diff changeset
2711
kono
parents: 67
diff changeset
2712 stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
2713 if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
kono
parents: 67
diff changeset
2714 {
kono
parents: 67
diff changeset
2715 if (e->flags & EDGE_TRUE_VALUE)
kono
parents: 67
diff changeset
2716 gimple_cond_make_false (cond_stmt);
kono
parents: 67
diff changeset
2717 else if (e->flags & EDGE_FALSE_VALUE)
kono
parents: 67
diff changeset
2718 gimple_cond_make_true (cond_stmt);
kono
parents: 67
diff changeset
2719 else
kono
parents: 67
diff changeset
2720 gcc_unreachable ();
kono
parents: 67
diff changeset
2721 update_stmt (cond_stmt);
kono
parents: 67
diff changeset
2722 }
kono
parents: 67
diff changeset
2723 else
kono
parents: 67
diff changeset
2724 {
kono
parents: 67
diff changeset
2725 /* Todo: handle other cases. Note that unreachable switch case
kono
parents: 67
diff changeset
2726 statements have already been removed. */
kono
parents: 67
diff changeset
2727 continue;
kono
parents: 67
diff changeset
2728 }
kono
parents: 67
diff changeset
2729
kono
parents: 67
diff changeset
2730 ret = true;
kono
parents: 67
diff changeset
2731 }
kono
parents: 67
diff changeset
2732
kono
parents: 67
diff changeset
2733 return ret;
kono
parents: 67
diff changeset
2734 }
kono
parents: 67
diff changeset
2735
kono
parents: 67
diff changeset
2736 /* Optimize
kono
parents: 67
diff changeset
2737 mask_2 = 1 << cnt_1;
kono
parents: 67
diff changeset
2738 _4 = __atomic_fetch_or_* (ptr_6, mask_2, _3);
kono
parents: 67
diff changeset
2739 _5 = _4 & mask_2;
kono
parents: 67
diff changeset
2740 to
kono
parents: 67
diff changeset
2741 _4 = ATOMIC_BIT_TEST_AND_SET (ptr_6, cnt_1, 0, _3);
kono
parents: 67
diff changeset
2742 _5 = _4;
kono
parents: 67
diff changeset
2743 If _5 is only used in _5 != 0 or _5 == 0 comparisons, 1
kono
parents: 67
diff changeset
2744 is passed instead of 0, and the builtin just returns a zero
kono
parents: 67
diff changeset
2745 or 1 value instead of the actual bit.
kono
parents: 67
diff changeset
2746 Similarly for __sync_fetch_and_or_* (without the ", _3" part
kono
parents: 67
diff changeset
2747 in there), and/or if mask_2 is a power of 2 constant.
kono
parents: 67
diff changeset
2748 Similarly for xor instead of or, use ATOMIC_BIT_TEST_AND_COMPLEMENT
kono
parents: 67
diff changeset
2749 in that case. And similarly for and instead of or, except that
kono
parents: 67
diff changeset
2750 the second argument to the builtin needs to be one's complement
kono
parents: 67
diff changeset
2751 of the mask instead of mask. */
kono
parents: 67
diff changeset
2752
kono
parents: 67
diff changeset
2753 static void
kono
parents: 67
diff changeset
2754 optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
kono
parents: 67
diff changeset
2755 enum internal_fn fn, bool has_model_arg,
kono
parents: 67
diff changeset
2756 bool after)
kono
parents: 67
diff changeset
2757 {
kono
parents: 67
diff changeset
2758 gimple *call = gsi_stmt (*gsip);
kono
parents: 67
diff changeset
2759 tree lhs = gimple_call_lhs (call);
kono
parents: 67
diff changeset
2760 use_operand_p use_p;
kono
parents: 67
diff changeset
2761 gimple *use_stmt;
kono
parents: 67
diff changeset
2762 tree mask, bit;
kono
parents: 67
diff changeset
2763 optab optab;
kono
parents: 67
diff changeset
2764
kono
parents: 67
diff changeset
2765 if (!flag_inline_atomics
kono
parents: 67
diff changeset
2766 || optimize_debug
kono
parents: 67
diff changeset
2767 || !gimple_call_builtin_p (call, BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
2768 || !lhs
kono
parents: 67
diff changeset
2769 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
kono
parents: 67
diff changeset
2770 || !single_imm_use (lhs, &use_p, &use_stmt)
kono
parents: 67
diff changeset
2771 || !is_gimple_assign (use_stmt)
kono
parents: 67
diff changeset
2772 || gimple_assign_rhs_code (use_stmt) != BIT_AND_EXPR
kono
parents: 67
diff changeset
2773 || !gimple_vdef (call))
kono
parents: 67
diff changeset
2774 return;
kono
parents: 67
diff changeset
2775
kono
parents: 67
diff changeset
2776 switch (fn)
kono
parents: 67
diff changeset
2777 {
kono
parents: 67
diff changeset
2778 case IFN_ATOMIC_BIT_TEST_AND_SET:
kono
parents: 67
diff changeset
2779 optab = atomic_bit_test_and_set_optab;
kono
parents: 67
diff changeset
2780 break;
kono
parents: 67
diff changeset
2781 case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT:
kono
parents: 67
diff changeset
2782 optab = atomic_bit_test_and_complement_optab;
kono
parents: 67
diff changeset
2783 break;
kono
parents: 67
diff changeset
2784 case IFN_ATOMIC_BIT_TEST_AND_RESET:
kono
parents: 67
diff changeset
2785 optab = atomic_bit_test_and_reset_optab;
kono
parents: 67
diff changeset
2786 break;
kono
parents: 67
diff changeset
2787 default:
kono
parents: 67
diff changeset
2788 return;
kono
parents: 67
diff changeset
2789 }
kono
parents: 67
diff changeset
2790
kono
parents: 67
diff changeset
2791 if (optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs))) == CODE_FOR_nothing)
kono
parents: 67
diff changeset
2792 return;
kono
parents: 67
diff changeset
2793
kono
parents: 67
diff changeset
2794 mask = gimple_call_arg (call, 1);
kono
parents: 67
diff changeset
2795 tree use_lhs = gimple_assign_lhs (use_stmt);
kono
parents: 67
diff changeset
2796 if (!use_lhs)
kono
parents: 67
diff changeset
2797 return;
kono
parents: 67
diff changeset
2798
kono
parents: 67
diff changeset
2799 if (TREE_CODE (mask) == INTEGER_CST)
kono
parents: 67
diff changeset
2800 {
kono
parents: 67
diff changeset
2801 if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET)
kono
parents: 67
diff changeset
2802 mask = const_unop (BIT_NOT_EXPR, TREE_TYPE (mask), mask);
kono
parents: 67
diff changeset
2803 mask = fold_convert (TREE_TYPE (lhs), mask);
kono
parents: 67
diff changeset
2804 int ibit = tree_log2 (mask);
kono
parents: 67
diff changeset
2805 if (ibit < 0)
kono
parents: 67
diff changeset
2806 return;
kono
parents: 67
diff changeset
2807 bit = build_int_cst (TREE_TYPE (lhs), ibit);
kono
parents: 67
diff changeset
2808 }
kono
parents: 67
diff changeset
2809 else if (TREE_CODE (mask) == SSA_NAME)
kono
parents: 67
diff changeset
2810 {
kono
parents: 67
diff changeset
2811 gimple *g = SSA_NAME_DEF_STMT (mask);
kono
parents: 67
diff changeset
2812 if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET)
kono
parents: 67
diff changeset
2813 {
kono
parents: 67
diff changeset
2814 if (!is_gimple_assign (g)
kono
parents: 67
diff changeset
2815 || gimple_assign_rhs_code (g) != BIT_NOT_EXPR)
kono
parents: 67
diff changeset
2816 return;
kono
parents: 67
diff changeset
2817 mask = gimple_assign_rhs1 (g);
kono
parents: 67
diff changeset
2818 if (TREE_CODE (mask) != SSA_NAME)
kono
parents: 67
diff changeset
2819 return;
kono
parents: 67
diff changeset
2820 g = SSA_NAME_DEF_STMT (mask);
kono
parents: 67
diff changeset
2821 }
kono
parents: 67
diff changeset
2822 if (!is_gimple_assign (g)
kono
parents: 67
diff changeset
2823 || gimple_assign_rhs_code (g) != LSHIFT_EXPR
kono
parents: 67
diff changeset
2824 || !integer_onep (gimple_assign_rhs1 (g)))
kono
parents: 67
diff changeset
2825 return;
kono
parents: 67
diff changeset
2826 bit = gimple_assign_rhs2 (g);
kono
parents: 67
diff changeset
2827 }
kono
parents: 67
diff changeset
2828 else
kono
parents: 67
diff changeset
2829 return;
kono
parents: 67
diff changeset
2830
kono
parents: 67
diff changeset
2831 if (gimple_assign_rhs1 (use_stmt) == lhs)
kono
parents: 67
diff changeset
2832 {
kono
parents: 67
diff changeset
2833 if (!operand_equal_p (gimple_assign_rhs2 (use_stmt), mask, 0))
kono
parents: 67
diff changeset
2834 return;
kono
parents: 67
diff changeset
2835 }
kono
parents: 67
diff changeset
2836 else if (gimple_assign_rhs2 (use_stmt) != lhs
kono
parents: 67
diff changeset
2837 || !operand_equal_p (gimple_assign_rhs1 (use_stmt), mask, 0))
kono
parents: 67
diff changeset
2838 return;
kono
parents: 67
diff changeset
2839
kono
parents: 67
diff changeset
2840 bool use_bool = true;
kono
parents: 67
diff changeset
2841 bool has_debug_uses = false;
kono
parents: 67
diff changeset
2842 imm_use_iterator iter;
kono
parents: 67
diff changeset
2843 gimple *g;
kono
parents: 67
diff changeset
2844
kono
parents: 67
diff changeset
2845 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs))
kono
parents: 67
diff changeset
2846 use_bool = false;
kono
parents: 67
diff changeset
2847 FOR_EACH_IMM_USE_STMT (g, iter, use_lhs)
kono
parents: 67
diff changeset
2848 {
kono
parents: 67
diff changeset
2849 enum tree_code code = ERROR_MARK;
kono
parents: 67
diff changeset
2850 tree op0 = NULL_TREE, op1 = NULL_TREE;
kono
parents: 67
diff changeset
2851 if (is_gimple_debug (g))
kono
parents: 67
diff changeset
2852 {
kono
parents: 67
diff changeset
2853 has_debug_uses = true;
kono
parents: 67
diff changeset
2854 continue;
kono
parents: 67
diff changeset
2855 }
kono
parents: 67
diff changeset
2856 else if (is_gimple_assign (g))
kono
parents: 67
diff changeset
2857 switch (gimple_assign_rhs_code (g))
kono
parents: 67
diff changeset
2858 {
kono
parents: 67
diff changeset
2859 case COND_EXPR:
kono
parents: 67
diff changeset
2860 op1 = gimple_assign_rhs1 (g);
kono
parents: 67
diff changeset
2861 code = TREE_CODE (op1);
kono
parents: 67
diff changeset
2862 op0 = TREE_OPERAND (op1, 0);
kono
parents: 67
diff changeset
2863 op1 = TREE_OPERAND (op1, 1);
kono
parents: 67
diff changeset
2864 break;
kono
parents: 67
diff changeset
2865 case EQ_EXPR:
kono
parents: 67
diff changeset
2866 case NE_EXPR:
kono
parents: 67
diff changeset
2867 code = gimple_assign_rhs_code (g);
kono
parents: 67
diff changeset
2868 op0 = gimple_assign_rhs1 (g);
kono
parents: 67
diff changeset
2869 op1 = gimple_assign_rhs2 (g);
kono
parents: 67
diff changeset
2870 break;
kono
parents: 67
diff changeset
2871 default:
kono
parents: 67
diff changeset
2872 break;
kono
parents: 67
diff changeset
2873 }
kono
parents: 67
diff changeset
2874 else if (gimple_code (g) == GIMPLE_COND)
kono
parents: 67
diff changeset
2875 {
kono
parents: 67
diff changeset
2876 code = gimple_cond_code (g);
kono
parents: 67
diff changeset
2877 op0 = gimple_cond_lhs (g);
kono
parents: 67
diff changeset
2878 op1 = gimple_cond_rhs (g);
kono
parents: 67
diff changeset
2879 }
kono
parents: 67
diff changeset
2880
kono
parents: 67
diff changeset
2881 if ((code == EQ_EXPR || code == NE_EXPR)
kono
parents: 67
diff changeset
2882 && op0 == use_lhs
kono
parents: 67
diff changeset
2883 && integer_zerop (op1))
kono
parents: 67
diff changeset
2884 {
kono
parents: 67
diff changeset
2885 use_operand_p use_p;
kono
parents: 67
diff changeset
2886 int n = 0;
kono
parents: 67
diff changeset
2887 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
kono
parents: 67
diff changeset
2888 n++;
kono
parents: 67
diff changeset
2889 if (n == 1)
kono
parents: 67
diff changeset
2890 continue;
kono
parents: 67
diff changeset
2891 }
kono
parents: 67
diff changeset
2892
kono
parents: 67
diff changeset
2893 use_bool = false;
kono
parents: 67
diff changeset
2894 BREAK_FROM_IMM_USE_STMT (iter);
kono
parents: 67
diff changeset
2895 }
kono
parents: 67
diff changeset
2896
kono
parents: 67
diff changeset
2897 tree new_lhs = make_ssa_name (TREE_TYPE (lhs));
kono
parents: 67
diff changeset
2898 tree flag = build_int_cst (TREE_TYPE (lhs), use_bool);
kono
parents: 67
diff changeset
2899 if (has_model_arg)
kono
parents: 67
diff changeset
2900 g = gimple_build_call_internal (fn, 4, gimple_call_arg (call, 0),
kono
parents: 67
diff changeset
2901 bit, flag, gimple_call_arg (call, 2));
kono
parents: 67
diff changeset
2902 else
kono
parents: 67
diff changeset
2903 g = gimple_build_call_internal (fn, 3, gimple_call_arg (call, 0),
kono
parents: 67
diff changeset
2904 bit, flag);
kono
parents: 67
diff changeset
2905 gimple_call_set_lhs (g, new_lhs);
kono
parents: 67
diff changeset
2906 gimple_set_location (g, gimple_location (call));
kono
parents: 67
diff changeset
2907 gimple_set_vuse (g, gimple_vuse (call));
kono
parents: 67
diff changeset
2908 gimple_set_vdef (g, gimple_vdef (call));
kono
parents: 67
diff changeset
2909 bool throws = stmt_can_throw_internal (call);
kono
parents: 67
diff changeset
2910 gimple_call_set_nothrow (as_a <gcall *> (g),
kono
parents: 67
diff changeset
2911 gimple_call_nothrow_p (as_a <gcall *> (call)));
kono
parents: 67
diff changeset
2912 SSA_NAME_DEF_STMT (gimple_vdef (call)) = g;
kono
parents: 67
diff changeset
2913 gimple_stmt_iterator gsi = *gsip;
kono
parents: 67
diff changeset
2914 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
kono
parents: 67
diff changeset
2915 edge e = NULL;
kono
parents: 67
diff changeset
2916 if (throws)
kono
parents: 67
diff changeset
2917 {
kono
parents: 67
diff changeset
2918 maybe_clean_or_replace_eh_stmt (call, g);
kono
parents: 67
diff changeset
2919 if (after || (use_bool && has_debug_uses))
kono
parents: 67
diff changeset
2920 e = find_fallthru_edge (gsi_bb (gsi)->succs);
kono
parents: 67
diff changeset
2921 }
kono
parents: 67
diff changeset
2922 if (after)
kono
parents: 67
diff changeset
2923 {
kono
parents: 67
diff changeset
2924 /* The internal function returns the value of the specified bit
kono
parents: 67
diff changeset
2925 before the atomic operation. If we are interested in the value
kono
parents: 67
diff changeset
2926 of the specified bit after the atomic operation (makes only sense
kono
parents: 67
diff changeset
2927 for xor, otherwise the bit content is compile time known),
kono
parents: 67
diff changeset
2928 we need to invert the bit. */
kono
parents: 67
diff changeset
2929 g = gimple_build_assign (make_ssa_name (TREE_TYPE (lhs)),
kono
parents: 67
diff changeset
2930 BIT_XOR_EXPR, new_lhs,
kono
parents: 67
diff changeset
2931 use_bool ? build_int_cst (TREE_TYPE (lhs), 1)
kono
parents: 67
diff changeset
2932 : mask);
kono
parents: 67
diff changeset
2933 new_lhs = gimple_assign_lhs (g);
kono
parents: 67
diff changeset
2934 if (throws)
kono
parents: 67
diff changeset
2935 {
kono
parents: 67
diff changeset
2936 gsi_insert_on_edge_immediate (e, g);
kono
parents: 67
diff changeset
2937 gsi = gsi_for_stmt (g);
kono
parents: 67
diff changeset
2938 }
kono
parents: 67
diff changeset
2939 else
kono
parents: 67
diff changeset
2940 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
kono
parents: 67
diff changeset
2941 }
kono
parents: 67
diff changeset
2942 if (use_bool && has_debug_uses)
kono
parents: 67
diff changeset
2943 {
kono
parents: 67
diff changeset
2944 tree temp = NULL_TREE;
kono
parents: 67
diff changeset
2945 if (!throws || after || single_pred_p (e->dest))
kono
parents: 67
diff changeset
2946 {
kono
parents: 67
diff changeset
2947 temp = make_node (DEBUG_EXPR_DECL);
kono
parents: 67
diff changeset
2948 DECL_ARTIFICIAL (temp) = 1;
kono
parents: 67
diff changeset
2949 TREE_TYPE (temp) = TREE_TYPE (lhs);
kono
parents: 67
diff changeset
2950 SET_DECL_MODE (temp, TYPE_MODE (TREE_TYPE (lhs)));
kono
parents: 67
diff changeset
2951 tree t = build2 (LSHIFT_EXPR, TREE_TYPE (lhs), new_lhs, bit);
kono
parents: 67
diff changeset
2952 g = gimple_build_debug_bind (temp, t, g);
kono
parents: 67
diff changeset
2953 if (throws && !after)
kono
parents: 67
diff changeset
2954 {
kono
parents: 67
diff changeset
2955 gsi = gsi_after_labels (e->dest);
kono
parents: 67
diff changeset
2956 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
kono
parents: 67
diff changeset
2957 }
kono
parents: 67
diff changeset
2958 else
kono
parents: 67
diff changeset
2959 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
kono
parents: 67
diff changeset
2960 }
kono
parents: 67
diff changeset
2961 FOR_EACH_IMM_USE_STMT (g, iter, use_lhs)
kono
parents: 67
diff changeset
2962 if (is_gimple_debug (g))
kono
parents: 67
diff changeset
2963 {
kono
parents: 67
diff changeset
2964 use_operand_p use_p;
kono
parents: 67
diff changeset
2965 if (temp == NULL_TREE)
kono
parents: 67
diff changeset
2966 gimple_debug_bind_reset_value (g);
kono
parents: 67
diff changeset
2967 else
kono
parents: 67
diff changeset
2968 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
kono
parents: 67
diff changeset
2969 SET_USE (use_p, temp);
kono
parents: 67
diff changeset
2970 update_stmt (g);
kono
parents: 67
diff changeset
2971 }
kono
parents: 67
diff changeset
2972 }
kono
parents: 67
diff changeset
2973 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_lhs)
kono
parents: 67
diff changeset
2974 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs);
kono
parents: 67
diff changeset
2975 replace_uses_by (use_lhs, new_lhs);
kono
parents: 67
diff changeset
2976 gsi = gsi_for_stmt (use_stmt);
kono
parents: 67
diff changeset
2977 gsi_remove (&gsi, true);
kono
parents: 67
diff changeset
2978 release_defs (use_stmt);
kono
parents: 67
diff changeset
2979 gsi_remove (gsip, true);
kono
parents: 67
diff changeset
2980 release_ssa_name (lhs);
kono
parents: 67
diff changeset
2981 }
kono
parents: 67
diff changeset
2982
kono
parents: 67
diff changeset
2983 /* Optimize
kono
parents: 67
diff changeset
2984 a = {};
kono
parents: 67
diff changeset
2985 b = a;
kono
parents: 67
diff changeset
2986 into
kono
parents: 67
diff changeset
2987 a = {};
kono
parents: 67
diff changeset
2988 b = {};
kono
parents: 67
diff changeset
2989 Similarly for memset (&a, ..., sizeof (a)); instead of a = {};
kono
parents: 67
diff changeset
2990 and/or memcpy (&b, &a, sizeof (a)); instead of b = a; */
kono
parents: 67
diff changeset
2991
kono
parents: 67
diff changeset
2992 static void
kono
parents: 67
diff changeset
2993 optimize_memcpy (gimple_stmt_iterator *gsip, tree dest, tree src, tree len)
kono
parents: 67
diff changeset
2994 {
kono
parents: 67
diff changeset
2995 gimple *stmt = gsi_stmt (*gsip);
kono
parents: 67
diff changeset
2996 if (gimple_has_volatile_ops (stmt))
kono
parents: 67
diff changeset
2997 return;
kono
parents: 67
diff changeset
2998
kono
parents: 67
diff changeset
2999 tree vuse = gimple_vuse (stmt);
kono
parents: 67
diff changeset
3000 if (vuse == NULL)
kono
parents: 67
diff changeset
3001 return;
kono
parents: 67
diff changeset
3002
kono
parents: 67
diff changeset
3003 gimple *defstmt = SSA_NAME_DEF_STMT (vuse);
kono
parents: 67
diff changeset
3004 tree src2 = NULL_TREE, len2 = NULL_TREE;
kono
parents: 67
diff changeset
3005 HOST_WIDE_INT offset, offset2;
kono
parents: 67
diff changeset
3006 tree val = integer_zero_node;
kono
parents: 67
diff changeset
3007 if (gimple_store_p (defstmt)
kono
parents: 67
diff changeset
3008 && gimple_assign_single_p (defstmt)
kono
parents: 67
diff changeset
3009 && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR
kono
parents: 67
diff changeset
3010 && !gimple_clobber_p (defstmt))
kono
parents: 67
diff changeset
3011 src2 = gimple_assign_lhs (defstmt);
kono
parents: 67
diff changeset
3012 else if (gimple_call_builtin_p (defstmt, BUILT_IN_MEMSET)
kono
parents: 67
diff changeset
3013 && TREE_CODE (gimple_call_arg (defstmt, 0)) == ADDR_EXPR
kono
parents: 67
diff changeset
3014 && TREE_CODE (gimple_call_arg (defstmt, 1)) == INTEGER_CST)
kono
parents: 67
diff changeset
3015 {
kono
parents: 67
diff changeset
3016 src2 = TREE_OPERAND (gimple_call_arg (defstmt, 0), 0);
kono
parents: 67
diff changeset
3017 len2 = gimple_call_arg (defstmt, 2);
kono
parents: 67
diff changeset
3018 val = gimple_call_arg (defstmt, 1);
kono
parents: 67
diff changeset
3019 /* For non-0 val, we'd have to transform stmt from assignment
kono
parents: 67
diff changeset
3020 into memset (only if dest is addressable). */
kono
parents: 67
diff changeset
3021 if (!integer_zerop (val) && is_gimple_assign (stmt))
kono
parents: 67
diff changeset
3022 src2 = NULL_TREE;
kono
parents: 67
diff changeset
3023 }
kono
parents: 67
diff changeset
3024
kono
parents: 67
diff changeset
3025 if (src2 == NULL_TREE)
kono
parents: 67
diff changeset
3026 return;
kono
parents: 67
diff changeset
3027
kono
parents: 67
diff changeset
3028 if (len == NULL_TREE)
kono
parents: 67
diff changeset
3029 len = (TREE_CODE (src) == COMPONENT_REF
kono
parents: 67
diff changeset
3030 ? DECL_SIZE_UNIT (TREE_OPERAND (src, 1))
kono
parents: 67
diff changeset
3031 : TYPE_SIZE_UNIT (TREE_TYPE (src)));
kono
parents: 67
diff changeset
3032 if (len2 == NULL_TREE)
kono
parents: 67
diff changeset
3033 len2 = (TREE_CODE (src2) == COMPONENT_REF
kono
parents: 67
diff changeset
3034 ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1))
kono
parents: 67
diff changeset
3035 : TYPE_SIZE_UNIT (TREE_TYPE (src2)));
kono
parents: 67
diff changeset
3036 if (len == NULL_TREE
kono
parents: 67
diff changeset
3037 || TREE_CODE (len) != INTEGER_CST
kono
parents: 67
diff changeset
3038 || len2 == NULL_TREE
kono
parents: 67
diff changeset
3039 || TREE_CODE (len2) != INTEGER_CST)
kono
parents: 67
diff changeset
3040 return;
kono
parents: 67
diff changeset
3041
kono
parents: 67
diff changeset
3042 src = get_addr_base_and_unit_offset (src, &offset);
kono
parents: 67
diff changeset
3043 src2 = get_addr_base_and_unit_offset (src2, &offset2);
kono
parents: 67
diff changeset
3044 if (src == NULL_TREE
kono
parents: 67
diff changeset
3045 || src2 == NULL_TREE
kono
parents: 67
diff changeset
3046 || offset < offset2)
kono
parents: 67
diff changeset
3047 return;
kono
parents: 67
diff changeset
3048
kono
parents: 67
diff changeset
3049 if (!operand_equal_p (src, src2, 0))
kono
parents: 67
diff changeset
3050 return;
kono
parents: 67
diff changeset
3051
kono
parents: 67
diff changeset
3052 /* [ src + offset2, src + offset2 + len2 - 1 ] is set to val.
kono
parents: 67
diff changeset
3053 Make sure that
kono
parents: 67
diff changeset
3054 [ src + offset, src + offset + len - 1 ] is a subset of that. */
kono
parents: 67
diff changeset
3055 if (wi::to_offset (len) + (offset - offset2) > wi::to_offset (len2))
kono
parents: 67
diff changeset
3056 return;
kono
parents: 67
diff changeset
3057
kono
parents: 67
diff changeset
3058 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3059 {
kono
parents: 67
diff changeset
3060 fprintf (dump_file, "Simplified\n ");
kono
parents: 67
diff changeset
3061 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
kono
parents: 67
diff changeset
3062 fprintf (dump_file, "after previous\n ");
kono
parents: 67
diff changeset
3063 print_gimple_stmt (dump_file, defstmt, 0, dump_flags);
kono
parents: 67
diff changeset
3064 }
kono
parents: 67
diff changeset
3065
kono
parents: 67
diff changeset
3066 /* For simplicity, don't change the kind of the stmt,
kono
parents: 67
diff changeset
3067 turn dest = src; into dest = {}; and memcpy (&dest, &src, len);
kono
parents: 67
diff changeset
3068 into memset (&dest, val, len);
kono
parents: 67
diff changeset
3069 In theory we could change dest = src into memset if dest
kono
parents: 67
diff changeset
3070 is addressable (maybe beneficial if val is not 0), or
kono
parents: 67
diff changeset
3071 memcpy (&dest, &src, len) into dest = {} if len is the size
kono
parents: 67
diff changeset
3072 of dest, dest isn't volatile. */
kono
parents: 67
diff changeset
3073 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
3074 {
kono
parents: 67
diff changeset
3075 tree ctor = build_constructor (TREE_TYPE (dest), NULL);
kono
parents: 67
diff changeset
3076 gimple_assign_set_rhs_from_tree (gsip, ctor);
kono
parents: 67
diff changeset
3077 update_stmt (stmt);
kono
parents: 67
diff changeset
3078 }
kono
parents: 67
diff changeset
3079 else /* If stmt is memcpy, transform it into memset. */
kono
parents: 67
diff changeset
3080 {
kono
parents: 67
diff changeset
3081 gcall *call = as_a <gcall *> (stmt);
kono
parents: 67
diff changeset
3082 tree fndecl = builtin_decl_implicit (BUILT_IN_MEMSET);
kono
parents: 67
diff changeset
3083 gimple_call_set_fndecl (call, fndecl);
kono
parents: 67
diff changeset
3084 gimple_call_set_fntype (call, TREE_TYPE (fndecl));
kono
parents: 67
diff changeset
3085 gimple_call_set_arg (call, 1, val);
kono
parents: 67
diff changeset
3086 update_stmt (stmt);
kono
parents: 67
diff changeset
3087 }
kono
parents: 67
diff changeset
3088
kono
parents: 67
diff changeset
3089 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
3090 {
kono
parents: 67
diff changeset
3091 fprintf (dump_file, "into\n ");
kono
parents: 67
diff changeset
3092 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
kono
parents: 67
diff changeset
3093 }
kono
parents: 67
diff changeset
3094 }
kono
parents: 67
diff changeset
3095
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3096 /* A simple pass that attempts to fold all builtin functions. This pass
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3097 is run after we've propagated as many constants as we can. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3098
111
kono
parents: 67
diff changeset
3099 namespace {
kono
parents: 67
diff changeset
3100
kono
parents: 67
diff changeset
3101 const pass_data pass_data_fold_builtins =
kono
parents: 67
diff changeset
3102 {
kono
parents: 67
diff changeset
3103 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
3104 "fab", /* name */
kono
parents: 67
diff changeset
3105 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
3106 TV_NONE, /* tv_id */
kono
parents: 67
diff changeset
3107 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
3108 0, /* properties_provided */
kono
parents: 67
diff changeset
3109 0, /* properties_destroyed */
kono
parents: 67
diff changeset
3110 0, /* todo_flags_start */
kono
parents: 67
diff changeset
3111 TODO_update_ssa, /* todo_flags_finish */
kono
parents: 67
diff changeset
3112 };
kono
parents: 67
diff changeset
3113
kono
parents: 67
diff changeset
3114 class pass_fold_builtins : public gimple_opt_pass
kono
parents: 67
diff changeset
3115 {
kono
parents: 67
diff changeset
3116 public:
kono
parents: 67
diff changeset
3117 pass_fold_builtins (gcc::context *ctxt)
kono
parents: 67
diff changeset
3118 : gimple_opt_pass (pass_data_fold_builtins, ctxt)
kono
parents: 67
diff changeset
3119 {}
kono
parents: 67
diff changeset
3120
kono
parents: 67
diff changeset
3121 /* opt_pass methods: */
kono
parents: 67
diff changeset
3122 opt_pass * clone () { return new pass_fold_builtins (m_ctxt); }
kono
parents: 67
diff changeset
3123 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
3124
kono
parents: 67
diff changeset
3125 }; // class pass_fold_builtins
kono
parents: 67
diff changeset
3126
kono
parents: 67
diff changeset
3127 unsigned int
kono
parents: 67
diff changeset
3128 pass_fold_builtins::execute (function *fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3129 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3130 bool cfg_changed = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3131 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3132 unsigned int todoflags = 0;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
3133
111
kono
parents: 67
diff changeset
3134 FOR_EACH_BB_FN (bb, fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3135 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3136 gimple_stmt_iterator i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3137 for (i = gsi_start_bb (bb); !gsi_end_p (i); )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3138 {
111
kono
parents: 67
diff changeset
3139 gimple *stmt, *old_stmt;
kono
parents: 67
diff changeset
3140 tree callee;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3141 enum built_in_function fcode;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3143 stmt = gsi_stmt (i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3145 if (gimple_code (stmt) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3146 {
111
kono
parents: 67
diff changeset
3147 /* Remove all *ssaname_N ={v} {CLOBBER}; stmts,
kono
parents: 67
diff changeset
3148 after the last GIMPLE DSE they aren't needed and might
kono
parents: 67
diff changeset
3149 unnecessarily keep the SSA_NAMEs live. */
kono
parents: 67
diff changeset
3150 if (gimple_clobber_p (stmt))
kono
parents: 67
diff changeset
3151 {
kono
parents: 67
diff changeset
3152 tree lhs = gimple_assign_lhs (stmt);
kono
parents: 67
diff changeset
3153 if (TREE_CODE (lhs) == MEM_REF
kono
parents: 67
diff changeset
3154 && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
kono
parents: 67
diff changeset
3155 {
kono
parents: 67
diff changeset
3156 unlink_stmt_vdef (stmt);
kono
parents: 67
diff changeset
3157 gsi_remove (&i, true);
kono
parents: 67
diff changeset
3158 release_defs (stmt);
kono
parents: 67
diff changeset
3159 continue;
kono
parents: 67
diff changeset
3160 }
kono
parents: 67
diff changeset
3161 }
kono
parents: 67
diff changeset
3162 else if (gimple_assign_load_p (stmt) && gimple_store_p (stmt))
kono
parents: 67
diff changeset
3163 optimize_memcpy (&i, gimple_assign_lhs (stmt),
kono
parents: 67
diff changeset
3164 gimple_assign_rhs1 (stmt), NULL_TREE);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3165 gsi_next (&i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3166 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3167 }
111
kono
parents: 67
diff changeset
3168
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3169 callee = gimple_call_fndecl (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3170 if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3171 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3172 gsi_next (&i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3173 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3174 }
111
kono
parents: 67
diff changeset
3175
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3176 fcode = DECL_FUNCTION_CODE (callee);
111
kono
parents: 67
diff changeset
3177 if (fold_stmt (&i))
kono
parents: 67
diff changeset
3178 ;
kono
parents: 67
diff changeset
3179 else
kono
parents: 67
diff changeset
3180 {
kono
parents: 67
diff changeset
3181 tree result = NULL_TREE;
kono
parents: 67
diff changeset
3182 switch (DECL_FUNCTION_CODE (callee))
kono
parents: 67
diff changeset
3183 {
kono
parents: 67
diff changeset
3184 case BUILT_IN_CONSTANT_P:
kono
parents: 67
diff changeset
3185 /* Resolve __builtin_constant_p. If it hasn't been
kono
parents: 67
diff changeset
3186 folded to integer_one_node by now, it's fairly
kono
parents: 67
diff changeset
3187 certain that the value simply isn't constant. */
kono
parents: 67
diff changeset
3188 result = integer_zero_node;
kono
parents: 67
diff changeset
3189 break;
kono
parents: 67
diff changeset
3190
kono
parents: 67
diff changeset
3191 case BUILT_IN_ASSUME_ALIGNED:
kono
parents: 67
diff changeset
3192 /* Remove __builtin_assume_aligned. */
kono
parents: 67
diff changeset
3193 result = gimple_call_arg (stmt, 0);
kono
parents: 67
diff changeset
3194 break;
kono
parents: 67
diff changeset
3195
kono
parents: 67
diff changeset
3196 case BUILT_IN_STACK_RESTORE:
kono
parents: 67
diff changeset
3197 result = optimize_stack_restore (i);
kono
parents: 67
diff changeset
3198 if (result)
kono
parents: 67
diff changeset
3199 break;
kono
parents: 67
diff changeset
3200 gsi_next (&i);
kono
parents: 67
diff changeset
3201 continue;
kono
parents: 67
diff changeset
3202
kono
parents: 67
diff changeset
3203 case BUILT_IN_UNREACHABLE:
kono
parents: 67
diff changeset
3204 if (optimize_unreachable (i))
kono
parents: 67
diff changeset
3205 cfg_changed = true;
kono
parents: 67
diff changeset
3206 break;
kono
parents: 67
diff changeset
3207
kono
parents: 67
diff changeset
3208 case BUILT_IN_ATOMIC_FETCH_OR_1:
kono
parents: 67
diff changeset
3209 case BUILT_IN_ATOMIC_FETCH_OR_2:
kono
parents: 67
diff changeset
3210 case BUILT_IN_ATOMIC_FETCH_OR_4:
kono
parents: 67
diff changeset
3211 case BUILT_IN_ATOMIC_FETCH_OR_8:
kono
parents: 67
diff changeset
3212 case BUILT_IN_ATOMIC_FETCH_OR_16:
kono
parents: 67
diff changeset
3213 optimize_atomic_bit_test_and (&i,
kono
parents: 67
diff changeset
3214 IFN_ATOMIC_BIT_TEST_AND_SET,
kono
parents: 67
diff changeset
3215 true, false);
kono
parents: 67
diff changeset
3216 break;
kono
parents: 67
diff changeset
3217 case BUILT_IN_SYNC_FETCH_AND_OR_1:
kono
parents: 67
diff changeset
3218 case BUILT_IN_SYNC_FETCH_AND_OR_2:
kono
parents: 67
diff changeset
3219 case BUILT_IN_SYNC_FETCH_AND_OR_4:
kono
parents: 67
diff changeset
3220 case BUILT_IN_SYNC_FETCH_AND_OR_8:
kono
parents: 67
diff changeset
3221 case BUILT_IN_SYNC_FETCH_AND_OR_16:
kono
parents: 67
diff changeset
3222 optimize_atomic_bit_test_and (&i,
kono
parents: 67
diff changeset
3223 IFN_ATOMIC_BIT_TEST_AND_SET,
kono
parents: 67
diff changeset
3224 false, false);
kono
parents: 67
diff changeset
3225 break;
kono
parents: 67
diff changeset
3226
kono
parents: 67
diff changeset
3227 case BUILT_IN_ATOMIC_FETCH_XOR_1:
kono
parents: 67
diff changeset
3228 case BUILT_IN_ATOMIC_FETCH_XOR_2:
kono
parents: 67
diff changeset
3229 case BUILT_IN_ATOMIC_FETCH_XOR_4:
kono
parents: 67
diff changeset
3230 case BUILT_IN_ATOMIC_FETCH_XOR_8:
kono
parents: 67
diff changeset
3231 case BUILT_IN_ATOMIC_FETCH_XOR_16:
kono
parents: 67
diff changeset
3232 optimize_atomic_bit_test_and
kono
parents: 67
diff changeset
3233 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, false);
kono
parents: 67
diff changeset
3234 break;
kono
parents: 67
diff changeset
3235 case BUILT_IN_SYNC_FETCH_AND_XOR_1:
kono
parents: 67
diff changeset
3236 case BUILT_IN_SYNC_FETCH_AND_XOR_2:
kono
parents: 67
diff changeset
3237 case BUILT_IN_SYNC_FETCH_AND_XOR_4:
kono
parents: 67
diff changeset
3238 case BUILT_IN_SYNC_FETCH_AND_XOR_8:
kono
parents: 67
diff changeset
3239 case BUILT_IN_SYNC_FETCH_AND_XOR_16:
kono
parents: 67
diff changeset
3240 optimize_atomic_bit_test_and
kono
parents: 67
diff changeset
3241 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3242 break;
111
kono
parents: 67
diff changeset
3243
kono
parents: 67
diff changeset
3244 case BUILT_IN_ATOMIC_XOR_FETCH_1:
kono
parents: 67
diff changeset
3245 case BUILT_IN_ATOMIC_XOR_FETCH_2:
kono
parents: 67
diff changeset
3246 case BUILT_IN_ATOMIC_XOR_FETCH_4:
kono
parents: 67
diff changeset
3247 case BUILT_IN_ATOMIC_XOR_FETCH_8:
kono
parents: 67
diff changeset
3248 case BUILT_IN_ATOMIC_XOR_FETCH_16:
kono
parents: 67
diff changeset
3249 optimize_atomic_bit_test_and
kono
parents: 67
diff changeset
3250 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, true);
kono
parents: 67
diff changeset
3251 break;
kono
parents: 67
diff changeset
3252 case BUILT_IN_SYNC_XOR_AND_FETCH_1:
kono
parents: 67
diff changeset
3253 case BUILT_IN_SYNC_XOR_AND_FETCH_2:
kono
parents: 67
diff changeset
3254 case BUILT_IN_SYNC_XOR_AND_FETCH_4:
kono
parents: 67
diff changeset
3255 case BUILT_IN_SYNC_XOR_AND_FETCH_8:
kono
parents: 67
diff changeset
3256 case BUILT_IN_SYNC_XOR_AND_FETCH_16:
kono
parents: 67
diff changeset
3257 optimize_atomic_bit_test_and
kono
parents: 67
diff changeset
3258 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, true);
kono
parents: 67
diff changeset
3259 break;
kono
parents: 67
diff changeset
3260
kono
parents: 67
diff changeset
3261 case BUILT_IN_ATOMIC_FETCH_AND_1:
kono
parents: 67
diff changeset
3262 case BUILT_IN_ATOMIC_FETCH_AND_2:
kono
parents: 67
diff changeset
3263 case BUILT_IN_ATOMIC_FETCH_AND_4:
kono
parents: 67
diff changeset
3264 case BUILT_IN_ATOMIC_FETCH_AND_8:
kono
parents: 67
diff changeset
3265 case BUILT_IN_ATOMIC_FETCH_AND_16:
kono
parents: 67
diff changeset
3266 optimize_atomic_bit_test_and (&i,
kono
parents: 67
diff changeset
3267 IFN_ATOMIC_BIT_TEST_AND_RESET,
kono
parents: 67
diff changeset
3268 true, false);
kono
parents: 67
diff changeset
3269 break;
kono
parents: 67
diff changeset
3270 case BUILT_IN_SYNC_FETCH_AND_AND_1:
kono
parents: 67
diff changeset
3271 case BUILT_IN_SYNC_FETCH_AND_AND_2:
kono
parents: 67
diff changeset
3272 case BUILT_IN_SYNC_FETCH_AND_AND_4:
kono
parents: 67
diff changeset
3273 case BUILT_IN_SYNC_FETCH_AND_AND_8:
kono
parents: 67
diff changeset
3274 case BUILT_IN_SYNC_FETCH_AND_AND_16:
kono
parents: 67
diff changeset
3275 optimize_atomic_bit_test_and (&i,
kono
parents: 67
diff changeset
3276 IFN_ATOMIC_BIT_TEST_AND_RESET,
kono
parents: 67
diff changeset
3277 false, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3278 break;
111
kono
parents: 67
diff changeset
3279
kono
parents: 67
diff changeset
3280 case BUILT_IN_MEMCPY:
kono
parents: 67
diff changeset
3281 if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
3282 && TREE_CODE (gimple_call_arg (stmt, 0)) == ADDR_EXPR
kono
parents: 67
diff changeset
3283 && TREE_CODE (gimple_call_arg (stmt, 1)) == ADDR_EXPR
kono
parents: 67
diff changeset
3284 && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST)
kono
parents: 67
diff changeset
3285 {
kono
parents: 67
diff changeset
3286 tree dest = TREE_OPERAND (gimple_call_arg (stmt, 0), 0);
kono
parents: 67
diff changeset
3287 tree src = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
kono
parents: 67
diff changeset
3288 tree len = gimple_call_arg (stmt, 2);
kono
parents: 67
diff changeset
3289 optimize_memcpy (&i, dest, src, len);
kono
parents: 67
diff changeset
3290 }
kono
parents: 67
diff changeset
3291 break;
kono
parents: 67
diff changeset
3292
kono
parents: 67
diff changeset
3293 case BUILT_IN_VA_START:
kono
parents: 67
diff changeset
3294 case BUILT_IN_VA_END:
kono
parents: 67
diff changeset
3295 case BUILT_IN_VA_COPY:
kono
parents: 67
diff changeset
3296 /* These shouldn't be folded before pass_stdarg. */
kono
parents: 67
diff changeset
3297 result = optimize_stdarg_builtin (stmt);
kono
parents: 67
diff changeset
3298 break;
kono
parents: 67
diff changeset
3299
kono
parents: 67
diff changeset
3300 default:;
kono
parents: 67
diff changeset
3301 }
kono
parents: 67
diff changeset
3302
kono
parents: 67
diff changeset
3303 if (!result)
kono
parents: 67
diff changeset
3304 {
kono
parents: 67
diff changeset
3305 gsi_next (&i);
kono
parents: 67
diff changeset
3306 continue;
kono
parents: 67
diff changeset
3307 }
kono
parents: 67
diff changeset
3308
kono
parents: 67
diff changeset
3309 if (!update_call_from_tree (&i, result))
kono
parents: 67
diff changeset
3310 gimplify_and_update_call_from_tree (&i, result);
kono
parents: 67
diff changeset
3311 }
kono
parents: 67
diff changeset
3312
kono
parents: 67
diff changeset
3313 todoflags |= TODO_update_address_taken;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3315 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3316 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3317 fprintf (dump_file, "Simplified\n ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3318 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3319 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3321 old_stmt = stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3322 stmt = gsi_stmt (i);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
3323 update_stmt (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3324
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3325 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3326 && gimple_purge_dead_eh_edges (bb))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3327 cfg_changed = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3329 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3330 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3331 fprintf (dump_file, "to\n ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3332 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3333 fprintf (dump_file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3334 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3335
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3336 /* Retry the same statement if it changed into another
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3337 builtin, there might be new opportunities now. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3338 if (gimple_code (stmt) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3339 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3340 gsi_next (&i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3341 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3342 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3343 callee = gimple_call_fndecl (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3344 if (!callee
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3345 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3346 || DECL_FUNCTION_CODE (callee) == fcode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3347 gsi_next (&i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3348 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3349 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
3350
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3351 /* Delete unreachable blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3352 if (cfg_changed)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3353 todoflags |= TODO_cleanup_cfg;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
3354
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3355 return todoflags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3356 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3357
111
kono
parents: 67
diff changeset
3358 } // anon namespace
kono
parents: 67
diff changeset
3359
kono
parents: 67
diff changeset
3360 gimple_opt_pass *
kono
parents: 67
diff changeset
3361 make_pass_fold_builtins (gcc::context *ctxt)
kono
parents: 67
diff changeset
3362 {
kono
parents: 67
diff changeset
3363 return new pass_fold_builtins (ctxt);
kono
parents: 67
diff changeset
3364 }
kono
parents: 67
diff changeset
3365
kono
parents: 67
diff changeset
3366 /* A simple pass that emits some warnings post IPA. */
kono
parents: 67
diff changeset
3367
kono
parents: 67
diff changeset
3368 namespace {
kono
parents: 67
diff changeset
3369
kono
parents: 67
diff changeset
3370 const pass_data pass_data_post_ipa_warn =
kono
parents: 67
diff changeset
3371 {
kono
parents: 67
diff changeset
3372 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
3373 "post_ipa_warn", /* name */
kono
parents: 67
diff changeset
3374 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
3375 TV_NONE, /* tv_id */
kono
parents: 67
diff changeset
3376 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
3377 0, /* properties_provided */
kono
parents: 67
diff changeset
3378 0, /* properties_destroyed */
kono
parents: 67
diff changeset
3379 0, /* todo_flags_start */
kono
parents: 67
diff changeset
3380 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
3381 };
kono
parents: 67
diff changeset
3382
kono
parents: 67
diff changeset
3383 class pass_post_ipa_warn : public gimple_opt_pass
kono
parents: 67
diff changeset
3384 {
kono
parents: 67
diff changeset
3385 public:
kono
parents: 67
diff changeset
3386 pass_post_ipa_warn (gcc::context *ctxt)
kono
parents: 67
diff changeset
3387 : gimple_opt_pass (pass_data_post_ipa_warn, ctxt)
kono
parents: 67
diff changeset
3388 {}
kono
parents: 67
diff changeset
3389
kono
parents: 67
diff changeset
3390 /* opt_pass methods: */
kono
parents: 67
diff changeset
3391 opt_pass * clone () { return new pass_post_ipa_warn (m_ctxt); }
kono
parents: 67
diff changeset
3392 virtual bool gate (function *) { return warn_nonnull != 0; }
kono
parents: 67
diff changeset
3393 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
3394
kono
parents: 67
diff changeset
3395 }; // class pass_fold_builtins
kono
parents: 67
diff changeset
3396
kono
parents: 67
diff changeset
3397 unsigned int
kono
parents: 67
diff changeset
3398 pass_post_ipa_warn::execute (function *fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3399 {
111
kono
parents: 67
diff changeset
3400 basic_block bb;
kono
parents: 67
diff changeset
3401
kono
parents: 67
diff changeset
3402 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
3403 {
kono
parents: 67
diff changeset
3404 gimple_stmt_iterator gsi;
kono
parents: 67
diff changeset
3405 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
kono
parents: 67
diff changeset
3406 {
kono
parents: 67
diff changeset
3407 gimple *stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
3408 if (!is_gimple_call (stmt) || gimple_no_warning_p (stmt))
kono
parents: 67
diff changeset
3409 continue;
kono
parents: 67
diff changeset
3410
kono
parents: 67
diff changeset
3411 if (warn_nonnull)
kono
parents: 67
diff changeset
3412 {
kono
parents: 67
diff changeset
3413 bitmap nonnullargs
kono
parents: 67
diff changeset
3414 = get_nonnull_args (gimple_call_fntype (stmt));
kono
parents: 67
diff changeset
3415 if (nonnullargs)
kono
parents: 67
diff changeset
3416 {
kono
parents: 67
diff changeset
3417 for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
kono
parents: 67
diff changeset
3418 {
kono
parents: 67
diff changeset
3419 tree arg = gimple_call_arg (stmt, i);
kono
parents: 67
diff changeset
3420 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
kono
parents: 67
diff changeset
3421 continue;
kono
parents: 67
diff changeset
3422 if (!integer_zerop (arg))
kono
parents: 67
diff changeset
3423 continue;
kono
parents: 67
diff changeset
3424 if (!bitmap_empty_p (nonnullargs)
kono
parents: 67
diff changeset
3425 && !bitmap_bit_p (nonnullargs, i))
kono
parents: 67
diff changeset
3426 continue;
kono
parents: 67
diff changeset
3427
kono
parents: 67
diff changeset
3428 location_t loc = gimple_location (stmt);
kono
parents: 67
diff changeset
3429 if (warning_at (loc, OPT_Wnonnull,
kono
parents: 67
diff changeset
3430 "argument %u null where non-null "
kono
parents: 67
diff changeset
3431 "expected", i + 1))
kono
parents: 67
diff changeset
3432 {
kono
parents: 67
diff changeset
3433 tree fndecl = gimple_call_fndecl (stmt);
kono
parents: 67
diff changeset
3434 if (fndecl && DECL_IS_BUILTIN (fndecl))
kono
parents: 67
diff changeset
3435 inform (loc, "in a call to built-in function %qD",
kono
parents: 67
diff changeset
3436 fndecl);
kono
parents: 67
diff changeset
3437 else if (fndecl)
kono
parents: 67
diff changeset
3438 inform (DECL_SOURCE_LOCATION (fndecl),
kono
parents: 67
diff changeset
3439 "in a call to function %qD declared here",
kono
parents: 67
diff changeset
3440 fndecl);
kono
parents: 67
diff changeset
3441
kono
parents: 67
diff changeset
3442 }
kono
parents: 67
diff changeset
3443 }
kono
parents: 67
diff changeset
3444 BITMAP_FREE (nonnullargs);
kono
parents: 67
diff changeset
3445 }
kono
parents: 67
diff changeset
3446 }
kono
parents: 67
diff changeset
3447 }
kono
parents: 67
diff changeset
3448 }
kono
parents: 67
diff changeset
3449 return 0;
kono
parents: 67
diff changeset
3450 }
kono
parents: 67
diff changeset
3451
kono
parents: 67
diff changeset
3452 } // anon namespace
kono
parents: 67
diff changeset
3453
kono
parents: 67
diff changeset
3454 gimple_opt_pass *
kono
parents: 67
diff changeset
3455 make_pass_post_ipa_warn (gcc::context *ctxt)
kono
parents: 67
diff changeset
3456 {
kono
parents: 67
diff changeset
3457 return new pass_post_ipa_warn (ctxt);
kono
parents: 67
diff changeset
3458 }