|
16 | 16 |
|
17 | 17 | #include <util/base_exceptions.h> |
18 | 18 | #include <util/exception_utils.h> |
| 19 | +#include <util/expr_util.h> |
19 | 20 | #include <util/invariant.h> |
20 | 21 | #include <util/prefix.h> |
21 | 22 | #include <util/std_expr.h> |
@@ -79,122 +80,6 @@ void goto_symex_statet::level1t::operator()(ssa_exprt &ssa_expr) |
79 | 80 | ssa_expr.set_level_1(it->second.second); |
80 | 81 | } |
81 | 82 |
|
82 | | -/// This function determines what expressions are to be propagated as |
83 | | -/// "constants" |
84 | | -bool goto_symex_statet::constant_propagation(const exprt &expr) const |
85 | | -{ |
86 | | - if(expr.is_constant()) |
87 | | - return true; |
88 | | - |
89 | | - if(expr.id()==ID_address_of) |
90 | | - { |
91 | | - const address_of_exprt &address_of_expr=to_address_of_expr(expr); |
92 | | - |
93 | | - return constant_propagation_reference(address_of_expr.object()); |
94 | | - } |
95 | | - else if(expr.id()==ID_typecast) |
96 | | - { |
97 | | - const typecast_exprt &typecast_expr=to_typecast_expr(expr); |
98 | | - |
99 | | - return constant_propagation(typecast_expr.op()); |
100 | | - } |
101 | | - else if(expr.id()==ID_plus) |
102 | | - { |
103 | | - forall_operands(it, expr) |
104 | | - if(!constant_propagation(*it)) |
105 | | - return false; |
106 | | - |
107 | | - return true; |
108 | | - } |
109 | | - else if(expr.id()==ID_mult) |
110 | | - { |
111 | | - // propagate stuff with sizeof in it |
112 | | - forall_operands(it, expr) |
113 | | - { |
114 | | - if(it->find(ID_C_c_sizeof_type).is_not_nil()) |
115 | | - return true; |
116 | | - else if(!constant_propagation(*it)) |
117 | | - return false; |
118 | | - } |
119 | | - |
120 | | - return true; |
121 | | - } |
122 | | - else if(expr.id()==ID_array) |
123 | | - { |
124 | | - forall_operands(it, expr) |
125 | | - if(!constant_propagation(*it)) |
126 | | - return false; |
127 | | - |
128 | | - return true; |
129 | | - } |
130 | | - else if(expr.id()==ID_array_of) |
131 | | - { |
132 | | - return constant_propagation(expr.op0()); |
133 | | - } |
134 | | - else if(expr.id()==ID_with) |
135 | | - { |
136 | | - // this is bad |
137 | | - /* |
138 | | - forall_operands(it, expr) |
139 | | - if(!constant_propagation(expr.op0())) |
140 | | - return false; |
141 | | -
|
142 | | - return true; |
143 | | - */ |
144 | | - return false; |
145 | | - } |
146 | | - else if(expr.id()==ID_struct) |
147 | | - { |
148 | | - forall_operands(it, expr) |
149 | | - if(!constant_propagation(*it)) |
150 | | - return false; |
151 | | - |
152 | | - return true; |
153 | | - } |
154 | | - else if(expr.id()==ID_union) |
155 | | - { |
156 | | - forall_operands(it, expr) |
157 | | - if(!constant_propagation(*it)) |
158 | | - return false; |
159 | | - |
160 | | - return true; |
161 | | - } |
162 | | - // byte_update works, byte_extract may be out-of-bounds |
163 | | - else if(expr.id()==ID_byte_update_big_endian || |
164 | | - expr.id()==ID_byte_update_little_endian) |
165 | | - { |
166 | | - forall_operands(it, expr) |
167 | | - if(!constant_propagation(*it)) |
168 | | - return false; |
169 | | - |
170 | | - return true; |
171 | | - } |
172 | | - |
173 | | - return false; |
174 | | -} |
175 | | - |
176 | | -/// this function determines which reference-typed expressions are constant |
177 | | -bool goto_symex_statet::constant_propagation_reference(const exprt &expr) const |
178 | | -{ |
179 | | - if(expr.id()==ID_symbol) |
180 | | - return true; |
181 | | - else if(expr.id()==ID_index) |
182 | | - { |
183 | | - const index_exprt &index_expr=to_index_expr(expr); |
184 | | - |
185 | | - return constant_propagation_reference(index_expr.array()) && |
186 | | - constant_propagation(index_expr.index()); |
187 | | - } |
188 | | - else if(expr.id()==ID_member) |
189 | | - { |
190 | | - return constant_propagation_reference(to_member_expr(expr).compound()); |
191 | | - } |
192 | | - else if(expr.id()==ID_string_constant) |
193 | | - return true; |
194 | | - |
195 | | - return false; |
196 | | -} |
197 | | - |
198 | 83 | /// write to a variable |
199 | 84 | static bool check_renaming(const exprt &expr); |
200 | 85 |
|
@@ -297,6 +182,41 @@ static void assert_l2_renaming(const exprt &expr) |
297 | 182 | #endif |
298 | 183 | } |
299 | 184 |
|
| 185 | +class goto_symex_is_constantt : public is_constantt |
| 186 | +{ |
| 187 | +protected: |
| 188 | + bool is_constant(const exprt &expr) const override |
| 189 | + { |
| 190 | + if(expr.id() == ID_mult) |
| 191 | + { |
| 192 | + // propagate stuff with sizeof in it |
| 193 | + forall_operands(it, expr) |
| 194 | + { |
| 195 | + if(it->find(ID_C_c_sizeof_type).is_not_nil()) |
| 196 | + return true; |
| 197 | + else if(!is_constant(*it)) |
| 198 | + return false; |
| 199 | + } |
| 200 | + |
| 201 | + return true; |
| 202 | + } |
| 203 | + else if(expr.id() == ID_with) |
| 204 | + { |
| 205 | + // this is bad |
| 206 | + /* |
| 207 | + forall_operands(it, expr) |
| 208 | + if(!is_constant(expr.op0())) |
| 209 | + return false; |
| 210 | +
|
| 211 | + return true; |
| 212 | + */ |
| 213 | + return false; |
| 214 | + } |
| 215 | + |
| 216 | + return is_constantt::is_constant(expr); |
| 217 | + } |
| 218 | +}; |
| 219 | + |
300 | 220 | void goto_symex_statet::assignment( |
301 | 221 | ssa_exprt &lhs, // L0/L1 |
302 | 222 | const exprt &rhs, // L2 |
@@ -341,7 +261,7 @@ void goto_symex_statet::assignment( |
341 | 261 |
|
342 | 262 | // for value propagation -- the RHS is L2 |
343 | 263 |
|
344 | | - if(!is_shared && record_value && constant_propagation(rhs)) |
| 264 | + if(!is_shared && record_value && goto_symex_is_constantt()(rhs)) |
345 | 265 | propagation.values[l1_identifier]=rhs; |
346 | 266 | else |
347 | 267 | propagation.remove(l1_identifier); |
|
0 commit comments