73 std::map<const IR::IDeclaration *, SymbolicValue *> map;
76 for (
auto v : map) result->map.emplace(v.first, v.second->clone());
82 if (filter(v.first, v.second)) result->map.emplace(v.first, v.second);
92 return ::P4::get(map, left);
95 void dbprint(std::ostream &out)
const {
98 if (!first) out << std::endl;
99 out << f.first <<
"=>" << f.second;
105 BUG_CHECK(map.size() == other->map.size(),
"Merging incompatible maps?");
107 auto v = other->get(d.first);
109 change = change || d.second->merge(v);
113 bool equals(
const ValueMap *other)
const {
114 BUG_CHECK(map.size() == other->map.size(),
"Incompatible maps compared");
116 auto ov = other->get(v.first);
118 if (!v.second->equals(ov))
return false;
129 bool evaluatingLeftValue =
false;
131 std::map<const IR::Expression *, SymbolicValue *> value;
134 LOG2(
"Symbolic evaluation of " << expression <<
" is " << v);
135 value.emplace(expression, v);
139 void postorder(
const IR::Constant *expression)
override;
140 void postorder(
const IR::BoolLiteral *expression)
override;
141 void postorder(
const IR::StringLiteral *expression)
override;
142 void postorder(
const IR::Operation_Ternary *expression)
override;
143 void postorder(
const IR::Operation_Binary *expression)
override;
144 void postorder(
const IR::Operation_Relation *expression)
override;
145 void postorder(
const IR::Operation_Unary *expression)
override;
146 void postorder(
const IR::PathExpression *expression)
override;
147 void postorder(
const IR::Member *expression)
override;
148 bool preorder(
const IR::ArrayIndex *expression)
override;
149 void postorder(
const IR::ArrayIndex *expression)
override;
150 void postorder(
const IR::ListExpression *expression)
override;
151 void postorder(
const IR::StructExpression *expression)
override;
152 void postorder(
const IR::MethodCallExpression *expression)
override;
153 void checkResult(
const IR::Expression *expression,
const IR::Expression *result);
154 void setNonConstant(
const IR::Expression *expression);
158 : refMap(refMap), typeMap(typeMap), valueMap(valueMap) {
161 CHECK_NULL(valueMap);
167 SymbolicValue *evaluate(
const IR::Expression *expression,
bool leftValue);
170 auto r = ::P4::get(value, expression);
171 BUG_CHECK(r !=
nullptr,
"no evaluation for %1%", expression);
229 enum class ValueState {
236 ScalarValue(ScalarValue::ValueState state,
const IR::Type *type)
241 bool isUninitialized()
const {
return state == ValueState::Uninitialized; }
242 bool isUnknown()
const {
return state == ValueState::NotConstant; }
243 bool isKnown()
const {
return state == ValueState::Constant; }
244 bool isScalar()
const override {
return true; }
245 void dbprint(std::ostream &out)
const override {
246 if (isUninitialized())
247 out <<
"uninitialized";
248 else if (isUnknown())
251 static ValueState init(
bool uninit) {
252 return uninit ? ValueState::Uninitialized : ValueState::NotConstant;
254 void setAllUnknown()
override { state = ScalarValue::ValueState::NotConstant; }
255 ValueState mergeState(ValueState other)
const {
256 if (state == ValueState::Uninitialized && other == ValueState::Uninitialized)
257 return ValueState::Uninitialized;
258 if (state == ValueState::Constant && other == ValueState::Constant)
260 return ValueState::Constant;
261 return ValueState::NotConstant;
263 bool hasUninitializedParts()
const override {
return state == ValueState::Uninitialized; }
293 :
ScalarValue(state, IR::Type_Boolean::get()), value(
false) {}
295 :
ScalarValue(ScalarValue::ValueState::Uninitialized, IR::Type_Boolean::get()),
298 :
ScalarValue(ScalarValue::ValueState::Constant, IR::Type_Boolean::get()),
299 value(constant->value) {}
302 :
ScalarValue(ScalarValue::ValueState::Constant, IR::Type_Boolean::get()), value(value) {}
303 void dbprint(std::ostream &out)
const override {
304 ScalarValue::dbprint(out);
305 if (!isKnown())
return;
306 out << (value ?
"true" :
"false");
310 result->state = state;
311 result->value = value;
323 const IR::Constant *constant;
325 :
ScalarValue(ScalarValue::ValueState::Uninitialized, type), constant(
nullptr) {}
326 SymbolicInteger(ScalarValue::ValueState state,
const IR::Type_Bits *type)
329 :
ScalarValue(ScalarValue::ValueState::Constant, constant->type), constant(constant) {
330 CHECK_NULL(constant);
333 void dbprint(std::ostream &out)
const override {
334 ScalarValue::dbprint(out);
335 if (isKnown()) out << constant->value;
339 result->state = state;
340 result->constant = constant;
352 const IR::StringLiteral *string;
354 :
ScalarValue(ScalarValue::ValueState::Uninitialized, type), string(
nullptr) {}
355 SymbolicString(ScalarValue::ValueState state,
const IR::Type_String *type)
358 :
ScalarValue(ScalarValue::ValueState::Constant, string->type), string(
string) {
362 void dbprint(std::ostream &out)
const override {
363 ScalarValue::dbprint(out);
364 if (isKnown()) out <<
string->value;
368 result->state = state;
369 result->string = string;
403 :
ScalarValue(ScalarValue::ValueState::Uninitialized, type) {}
407 :
ScalarValue(ScalarValue::ValueState::Constant, type), value(value) {}
409 void dbprint(std::ostream &out)
const override {
410 ScalarValue::dbprint(out);
411 if (isKnown()) out << value;
426 std::map<cstring, SymbolicValue *> fieldValue;
427 SymbolicStruct(
const IR::Type_StructLike *type,
bool uninitialized,
430 auto r = ::P4::get(fieldValue, field);
436 fieldValue[field] = value;
438 void dbprint(std::ostream &out)
const override;
439 bool isScalar()
const override {
return false; }
441 void setAllUnknown()
override;
445 bool hasUninitializedParts()
const override;
600 unsigned minimumStreamOffset;
607 :
SymbolicExtern(type), minimumStreamOffset(0), conservative(
false) {}
608 void dbprint(std::ostream &out)
const override {
609 out <<
"packet_in; offset =" << minimumStreamOffset
610 << (conservative ?
" (conservative)" :
"");
614 result->minimumStreamOffset = minimumStreamOffset;
615 result->conservative = conservative;
618 void setConservative() { conservative =
true; }
619 bool isConservative()
const {
return conservative; }
620 void advance(
unsigned width) { minimumStreamOffset += width; }
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24