|
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