|
16 | 16 |
|
17 | 17 | #include <util/invariant.h> |
18 | 18 | #include <util/base_exceptions.h> |
| 19 | +#include <util/expr_util.h> |
19 | 20 | #include <util/std_expr.h> |
20 | 21 | #include <util/prefix.h> |
21 | 22 |
|
@@ -79,125 +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 | | - if(expr.operands().size()!=1) |
191 | | - throw "member expects one operand"; |
192 | | - |
193 | | - return constant_propagation_reference(expr.op0()); |
194 | | - } |
195 | | - else if(expr.id()==ID_string_constant) |
196 | | - return true; |
197 | | - |
198 | | - return false; |
199 | | -} |
200 | | - |
201 | 83 | /// write to a variable |
202 | 84 | static bool check_renaming(const exprt &expr); |
203 | 85 |
|
@@ -306,6 +188,41 @@ static void assert_l2_renaming(const exprt &expr) |
306 | 188 | #endif |
307 | 189 | } |
308 | 190 |
|
| 191 | +class goto_symex_is_constantt : public is_constantt |
| 192 | +{ |
| 193 | +protected: |
| 194 | + bool is_constant(const exprt &expr) const override |
| 195 | + { |
| 196 | + if(expr.id()==ID_mult) |
| 197 | + { |
| 198 | + // propagate stuff with sizeof in it |
| 199 | + forall_operands(it, expr) |
| 200 | + { |
| 201 | + if(it->find(ID_C_c_sizeof_type).is_not_nil()) |
| 202 | + return true; |
| 203 | + else if(!is_constant(*it)) |
| 204 | + return false; |
| 205 | + } |
| 206 | + |
| 207 | + return true; |
| 208 | + } |
| 209 | + else if(expr.id()==ID_with) |
| 210 | + { |
| 211 | + // this is bad |
| 212 | + /* |
| 213 | + forall_operands(it, expr) |
| 214 | + if(!is_constant(expr.op0())) |
| 215 | + return false; |
| 216 | +
|
| 217 | + return true; |
| 218 | + */ |
| 219 | + return false; |
| 220 | + } |
| 221 | + |
| 222 | + return is_constantt::is_constant(expr); |
| 223 | + } |
| 224 | +}; |
| 225 | + |
309 | 226 | void goto_symex_statet::assignment( |
310 | 227 | ssa_exprt &lhs, // L0/L1 |
311 | 228 | const exprt &rhs, // L2 |
@@ -344,7 +261,7 @@ void goto_symex_statet::assignment( |
344 | 261 |
|
345 | 262 | // for value propagation -- the RHS is L2 |
346 | 263 |
|
347 | | - if(!is_shared && record_value && constant_propagation(rhs)) |
| 264 | + if(!is_shared && record_value && goto_symex_is_constantt(rhs)) |
348 | 265 | propagation.values[l1_identifier]=rhs; |
349 | 266 | else |
350 | 267 | propagation.remove(l1_identifier); |
|
0 commit comments