P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
def_use.h
1/*
2Copyright 2024 Intel Corp.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef MIDEND_DEF_USE_H_
18#define MIDEND_DEF_USE_H_
19
20#include "frontends/common/resolveReferences/resolveReferences.h"
21#include "ir/ir.h"
22#include "lib/bitrange.h"
23
24namespace P4 {
25
42class ComputeDefUse : public Inspector,
43 public ControlFlowVisitor,
44 public P4WriteContext,
46 ComputeDefUse *clone() const override { return new ComputeDefUse(*this); }
47 void flow_merge(Visitor &) override;
48 void flow_copy(ControlFlowVisitor &) override;
49 enum { SKIPPING, NORMAL, READ_ONLY, WRITE_ONLY } state = SKIPPING;
50
51 public:
52 // a location in the program. Includes the context from the visitor, which needs to
53 // be copied out of the Visitor::Context objects, as they are allocated on the stack and
54 // will become invalid as the IR traversal continues
55 struct loc_t {
56 const IR::Node *node;
57 const loc_t *parent;
58 bool operator<(const loc_t &a) const {
59 if (node != a.node) return node->id < a.node->id;
60 if (!a.parent) return parent != nullptr;
61 return *parent < *a.parent;
62 }
63 template <class T>
64 const T *find() const {
65 for (auto *p = this; p; p = p->parent) {
66 if (auto *t = p->node->to<T>()) return t;
67 }
68 return nullptr;
69 }
70 };
71
72 private:
73 std::set<loc_t> &cached_locs;
74 const loc_t *getLoc(const Visitor::Context *ctxt);
75 const loc_t *getLoc() { return getLoc(getChildContext()); }
76 const loc_t *getLoc(const IR::Node *, const Visitor::Context *);
77 const loc_t *getLoc(const IR::Node *n) { return getLoc(n, getChildContext()); }
78
79 // flow tracking info about defs live at the point we are currently visiting
80 struct def_info_t {
81 // definitions of a symbol (or part of a symbol) visible at this point in the
82 // program. `defs` will be empty if `live` is; if not those defs are visible only
83 // for those bits/elements/fields where live is set.
85 bitvec live;
86 def_info_t *parent = nullptr;
87 // track valid bit access for headers separate from the rest of the header
88 ordered_set<const loc_t *> valid_bit_defs;
89 // one of these maps will always be empty.
90 std::map<cstring, def_info_t> fields;
91 std::map<le_bitrange, def_info_t> slices; // also used for arrays
92 // keys in slices are always non-overlapping (checked by slices_sanity)
93 void slices_sanity();
94 std::map<le_bitrange, def_info_t>::iterator slices_overlap_begin(le_bitrange);
95 void erase_slice(le_bitrange);
96 void split_slice(le_bitrange);
97 void flow_merge(def_info_t &);
98 def_info_t() = default;
99 def_info_t(const def_info_t &);
100 def_info_t(def_info_t &&);
101 };
103 void add_uses(const loc_t *, def_info_t &);
104 void set_live_from_type(def_info_t &di, const IR::Type *type);
105
106 // computed defuse info for all uses and defs in the program
107 struct defuse_t {
108 // defs maps from all uses to their definitions
109 // uses maps from all definitions to their uses
110 // uses/defs are lvalue expressions, or param declarations.
113 } & defuse;
114 static const ordered_set<const loc_t *> empty;
115
116 profile_t init_apply(const IR::Node *root) override {
117 auto rv = Inspector::init_apply(root);
118 state = SKIPPING;
119 clear();
120 return rv;
121 }
122 bool preorder(const IR::P4Control *) override;
123 bool preorder(const IR::P4Table *) override;
124 bool preorder(const IR::P4Action *) override;
125 bool preorder(const IR::P4Parser *) override;
126 bool preorder(const IR::ParserState *) override;
127 void revisit(const IR::ParserState *) override;
128 void loop_revisit(const IR::ParserState *) override;
129 void postorder(const IR::ParserState *) override;
130 bool preorder(const IR::Type *) override { return false; }
131 bool preorder(const IR::Annotations *) override { return false; }
132 bool preorder(const IR::KeyElement *) override;
133 const IR::Expression *do_read(def_info_t &, const IR::Expression *, const Context *);
134 const IR::Expression *do_write(def_info_t &, const IR::Expression *, const Context *);
135 bool preorder(const IR::PathExpression *) override;
136 void loop_revisit(const IR::PathExpression *) override;
137 bool preorder(const IR::MethodCallExpression *) override;
138 void end_apply() override;
139
140 class SetupJoinPoints;
141 void applySetupJoinPoints(const IR::Node *root) override;
142 bool filter_join_point(const IR::Node *) override;
143
144 public:
145 ComputeDefUse()
146 : ResolutionContext(true), cached_locs(*new std::set<loc_t>), defuse(*new defuse_t) {
147 joinFlows = true;
148 }
149 void clear() {
150 cached_locs.clear();
151 def_info.clear();
152 defuse.defs.clear();
153 defuse.uses.clear();
154 }
155
156 const ordered_set<const loc_t *> &getDefs(const IR::Node *n) const {
157 auto it = defuse.defs.find(n);
158 return it == defuse.defs.end() ? empty : it->second;
159 }
160 const ordered_set<const loc_t *> &getUses(const IR::Node *n) const {
161 auto it = defuse.uses.find(n);
162 return it == defuse.uses.end() ? empty : it->second;
163 }
164
165 // for debugging
166 friend std::ostream &operator<<(std::ostream &, const loc_t &);
167 friend std::ostream &operator<<(std::ostream &, const defuse_t &);
168 friend std::ostream &operator<<(std::ostream &out, const ComputeDefUse &cdu) {
169 return out << cdu.defuse;
170 }
171};
172
173} // namespace P4
174
175#endif /* MIDEND_DEF_USE_H_ */
Compute defuse info within P4Parser and P4Control blocks in the midend.
Definition def_use.h:45
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:33
Definition bitvec.h:119
Definition ordered_map.h:30
Definition ordered_set.h:30
Definition applyOptionsPragmas.cpp:24
STL namespace.
Definition bitrange.h:512
Definition def_use.h:55