69 if (
auto tt = type->to<IR::Type_Tuple>())
70 BUG_CHECK(tt->getSize() == 0,
"%1%: tuples with fields are not base locations", tt);
71 else if (
auto ts = type->to<IR::Type_StructLike>())
72 BUG_CHECK(ts->fields.size() == 0,
"%1%: structs with fields are not base locations",
75 BUG_CHECK(type->is<IR::Type_Bits>() || type->is<IR::Type_Enum>() ||
76 type->is<IR::Type_Boolean>() || type->is<IR::Type_Var>() ||
77 type->is<IR::Type_Error>() || type->is<IR::Type_Varbits>() ||
78 type->is<IR::Type_Newtype>() || type->is<IR::Type_SerEnum>() ||
79 type->is<IR::Type_List>(),
80 "%1%: unexpected type", type);
83 void addLastIndexField(
LocationSet *)
const override {}
254 auto type = typeMap->getType(decl->getNode(),
true);
255 auto loc = factory.create(type, decl->getName() +
"/" + decl->externalName());
256 if (loc !=
nullptr) storage.emplace(decl, loc);
260 auto s = getStorage(decl);
261 if (s !=
nullptr)
return s;
266 auto result = ::get(storage, decl);
269 void dbprint(std::ostream &out)
const override {
270 for (
auto &it : storage) out << it.first <<
": " << it.second << Log::endl;
283 absl::InlinedVector<const IR::Node *, 8> stack;
298 std::size_t hash()
const;
299 void dbprint(std::ostream &out)
const override {
300 if (isBeforeStart()) {
301 out <<
"<BeforeStart>";
304 for (
auto n : stack) {
305 if (!first) out <<
"//";
312 auto l = stack.back();
314 (l->is<IR::AssignmentStatement>() || l->is<IR::MethodCallStatement>()))
315 out <<
"[[" << l <<
"]]";
318 void assign(
const ProgramPoint &context,
const IR::Node *node);
319 void assign(
const IR::Node *node) { stack.assign({node}); }
320 void clear() { stack.clear(); }
321 const IR::Node *last()
const {
return stack.empty() ? nullptr : stack.back(); }
322 bool isBeforeStart()
const {
return stack.empty(); }
323 auto begin()
const {
return stack.begin(); }
324 auto end()
const {
return stack.end(); }
325 ProgramPoint &operator=(
const ProgramPoint &) =
default;
326 ProgramPoint &operator=(ProgramPoint &&) =
default;
349 typedef absl::flat_hash_set<ProgramPoint, Util::Hash> Points;
351 explicit ProgramPoints(
const Points &points) : points(points) {}
360 void dbprint(std::ostream &out)
const override {
362 for (
auto p : points) out << p <<
" ";
365 size_t size()
const {
return points.size(); }
366 bool containsBeforeStart()
const {
369 Points::const_iterator begin()
const {
return points.cbegin(); }
370 Points::const_iterator end()
const {
return points.cend(); }
379 bool unreachable =
false;
384 : definitions(other.definitions), unreachable(other.unreachable) {}
391 definitions[loc] = point;
399 bool isUnreachable()
const {
return unreachable; }
401 return definitions.find(location) != definitions.end();
404 auto r = ::get(definitions, location);
405 BUG_CHECK(r !=
nullptr,
"no definitions found for %1%", location);
410 void dbprint(std::ostream &out)
const override {
412 out <<
" Unreachable" << Log::endl;
414 if (definitions.empty()) out <<
" Empty definitions";
416 for (
auto d : definitions) {
417 if (!first) out << Log::endl;
418 out <<
" " << *d.first <<
"=>" << *d.second;
424 bool empty()
const {
return definitions.empty(); }
425 size_t size()
const {
return definitions.size(); }
438 : storageMap(
new StorageMap(refMap, typeMap)) {}
440 auto it = atPoint.find(point);
441 if (it == atPoint.end()) {
442 if (emptyIfNotFound) {
444 setDefinitionsAt(point, defs,
false);
447 BUG(
"Unknown point %1% for definitions", &point);
453 auto it = atPoint.find(point);
454 if (it != atPoint.end()) {
455 LOG2(
"Overwriting definitions at " << point <<
": " << it->second <<
" with "
457 BUG_CHECK(
false,
"Overwriting definitions at %1%", point);
460 atPoint[point] = defs;
462 void dbprint(std::ostream &out)
const override {
463 for (
auto e : atPoint) out << e.first <<
" => " << e.second << Log::endl;
493 static int nest_count;
498 : allDefinitions(source->allDefinitions),
503 storageMap(source->storageMap),
505 virtualMethod(false) {
506 visitDagOnce =
false;
509 void enterScope(
const IR::ParameterList *parameters,
510 const IR::IndexedVector<IR::Declaration> *locals,
ProgramPoint startPoint,
512 void exitScope(
const IR::ParameterList *parameters,
513 const IR::IndexedVector<IR::Declaration> *locals);
514 Definitions *getDefinitionsAfter(
const IR::ParserState *state);
515 bool setDefinitions(
Definitions *defs,
const IR::Node *who =
nullptr,
bool overwrite =
false);
516 ProgramPoint getProgramPoint(
const IR::Node *node =
nullptr)
const;
517 const LocationSet *getWrites(
const IR::Expression *expression)
const {
518 auto result = ::get(
writes, expression);
519 BUG_CHECK(result !=
nullptr,
"No location set known for %1%", expression);
522 void expressionWrites(
const IR::Expression *expression,
const LocationSet *loc) {
523 CHECK_NULL(expression);
525 LOG3(expression << dbp(expression) <<
" writes " << loc);
526 BUG_CHECK(
writes.find(expression) ==
writes.end() || expression->is<IR::Literal>(),
527 "Expression %1% write set already set", expression);
528 writes.emplace(expression, loc);
530 void dbprint(std::ostream &out)
const override {
531 if (
writes.empty()) out <<
"No writes";
532 for (
auto &it :
writes) out << it.first <<
" writes " << it.second << Log::endl;
534 profile_t init_apply(
const IR::Node *root)
override {
535 auto rv = Inspector::init_apply(root);
536 LOG1(
"starting ComputWriteSet" << Log::indent);
537 if (nest_count++ == 0 && LOGGING(2)) {
539 nested_trace =
memuse.start();
543 void end_apply()
override {
544 LOG1(
"finished CWS" << Log::unindent);
545 if (--nest_count == 0 && LOGGING(2)) {
546 memuse.stop(nested_trace);
553 : allDefinitions(allDefinitions),
557 storageMap(allDefinitions->storageMap),
559 virtualMethod(false) {
560 CHECK_NULL(allDefinitions);
561 visitDagOnce =
false;
565 bool preorder(
const IR::Literal *expression)
override;
566 bool preorder(
const IR::Slice *expression)
override;
567 bool preorder(
const IR::TypeNameExpression *expression)
override;
568 bool preorder(
const IR::PathExpression *expression)
override;
569 bool preorder(
const IR::Member *expression)
override;
570 bool preorder(
const IR::ArrayIndex *expression)
override;
571 bool preorder(
const IR::Operation_Binary *expression)
override;
572 bool preorder(
const IR::Mux *expression)
override;
573 bool preorder(
const IR::SelectExpression *expression)
override;
574 bool preorder(
const IR::ListExpression *expression)
override;
575 bool preorder(
const IR::Operation_Unary *expression)
override;
576 bool preorder(
const IR::MethodCallExpression *expression)
override;
577 bool preorder(
const IR::DefaultExpression *expression)
override;
578 bool preorder(
const IR::Expression *expression)
override;
579 bool preorder(
const IR::InvalidHeader *expression)
override;
580 bool preorder(
const IR::InvalidHeaderUnion *expression)
override;
581 bool preorder(
const IR::P4ListExpression *expression)
override;
582 bool preorder(
const IR::HeaderStackExpression *expression)
override;
583 bool preorder(
const IR::StructExpression *expression)
override;
585 bool preorder(
const IR::P4Parser *parser)
override;
586 bool preorder(
const IR::P4Control *control)
override;
587 bool preorder(
const IR::P4Action *action)
override;
588 bool preorder(
const IR::P4Table *table)
override;
589 bool preorder(
const IR::Function *function)
override;
590 bool preorder(
const IR::AssignmentStatement *statement)
override;
591 bool preorder(
const IR::ReturnStatement *statement)
override;
592 bool preorder(
const IR::ExitStatement *statement)
override;
593 bool preorder(
const IR::IfStatement *statement)
override;
594 bool preorder(
const IR::BlockStatement *statement)
override;
595 bool preorder(
const IR::SwitchStatement *statement)
override;
596 bool preorder(
const IR::EmptyStatement *statement)
override;
597 bool preorder(
const IR::MethodCallStatement *statement)
override;
599 const LocationSet *writtenLocations(
const IR::Expression *expression) {
600 expression->apply(*
this);
601 return getWrites(expression);
Definitions * writes(ProgramPoint point, const LocationSet *locations) const
Point writes the specified LocationSet.
Definition def_use.cpp:344