36 public ControlFlowVisitor,
41 ComputeDefUse *clone()
const override {
42 auto *rv =
new ComputeDefUse(*
this);
44 LOG8(
"ComputeDefUse::clone " << rv->uid <<
" <- " << uid);
47 void flow_merge(
Visitor &)
override;
48 void flow_copy(ControlFlowVisitor &)
override;
49 bool operator==(
const ControlFlowVisitor &)
const override;
51 enum { SKIPPING, NORMAL, READ_ONLY, WRITE_ONLY } state = SKIPPING;
60 mutable size_t computedHash = 0;
61 bool operator<(
const loc_t &a)
const {
62 if (node != a.node)
return node->id < a.node->id;
63 if (!parent || !a.parent)
return parent !=
nullptr;
64 return *parent < *a.parent;
66 bool operator==(
const loc_t &a)
const {
67 if (node != a.node)
return false;
68 if (parent == a.parent)
return true;
69 if (!parent || !a.parent)
return false;
70 return *parent == *a.parent;
72 std::size_t hash()
const {
77 computedHash =
Util::Hash{}(node->id, parent->hash());
83 const T *find()
const {
84 for (
auto *p =
this; p; p = p->parent) {
85 if (
auto *t = p->node->to<T>())
return t;
94 std::unordered_set<loc_t> &cached_locs;
95 const loc_t *getLoc(
const Visitor::Context *ctxt);
96 const loc_t *getLoc() {
return getLoc(getChildContext()); }
97 const loc_t *getLoc(
const IR::Node *,
const Visitor::Context *);
98 const loc_t *getLoc(
const IR::Node *n) {
return getLoc(n, getChildContext()); }
109 def_info_t *parent =
nullptr;
111 locset_t valid_bit_defs;
113 std::map<cstring, def_info_t> fields;
114 std::map<le_bitrange, def_info_t> slices;
116 void slices_sanity();
117 std::map<le_bitrange, def_info_t>::iterator slices_overlap_begin(le_bitrange);
118 void erase_slice(le_bitrange);
119 void split_slice(le_bitrange);
120 void flow_merge(def_info_t &);
121 bool operator==(
const def_info_t &)
const;
122 bool operator!=(
const def_info_t &a)
const {
return !(*
this == a); }
123 def_info_t() =
default;
124 def_info_t(
const def_info_t &);
125 def_info_t(def_info_t &&);
126 def_info_t &operator=(
const def_info_t &);
127 def_info_t &operator=(def_info_t &&);
129 hvec_map<const IR::IDeclaration *, def_info_t> def_info;
130 void add_uses(
const loc_t *, def_info_t &);
131 void set_live_from_type(def_info_t &di,
const IR::Type *type);
138 hvec_map<const IR::Node *, locset_t> defs;
139 hvec_map<const IR::Node *, locset_t> uses;
141 static const locset_t empty;
143 profile_t init_apply(
const IR::Node *root)
override {
144 auto rv = Inspector::init_apply(root);
145 LOG3(
"## Midend ComputeDefUse");
151 bool preorder(
const IR::P4Control *)
override;
152 bool preorder(
const IR::P4Table *)
override;
153 bool preorder(
const IR::P4Action *)
override;
154 bool preorder(
const IR::P4Parser *)
override;
155 bool preorder(
const IR::Function *)
override;
156 bool preorder(
const IR::ParserState *)
override;
157 void revisit(
const IR::ParserState *)
override;
158 void loop_revisit(
const IR::ParserState *)
override;
159 void postorder(
const IR::ParserState *)
override;
160 bool preorder(
const IR::Type *)
override {
return false; }
161 bool preorder(
const IR::Vector<IR::Annotation> *)
override {
return false; }
162 bool preorder(
const IR::KeyElement *)
override;
163 bool preorder(
const IR::BaseAssignmentStatement *)
override;
164 const IR::Expression *do_read(def_info_t &,
const IR::Expression *,
const Context *);
165 const IR::Expression *do_write(def_info_t &,
const IR::Expression *,
const Context *);
166 bool preorder(
const IR::PathExpression *)
override;
167 void loop_revisit(
const IR::PathExpression *)
override;
168 bool preorder(
const IR::MethodCallExpression *)
override;
169 void end_apply()
override;
172 void applySetupJoinPoints(
const IR::Node *root)
override;
173 bool filter_join_point(
const IR::Node *)
override;
179 const locset_t &getDefs(
const IR::Node *n)
const {
180 auto it = defuse.defs.find(n);
181 return it == defuse.defs.end() ? empty : it->second;
183 const locset_t &getUses(
const IR::Node *n)
const {
184 auto it = defuse.uses.find(n);
185 return it == defuse.uses.end() ? empty : it->second;
189 friend std::ostream &operator<<(std::ostream &,
const loc_t &);
190 friend std::ostream &operator<<(std::ostream &,
const defuse_t &);
191 friend std::ostream &operator<<(std::ostream &out,
const ComputeDefUse &cdu) {
192 return out << cdu.defuse;
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:35
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13