19#ifndef BF_P4C_PHV_PHV_H_
20#define BF_P4C_PHV_PHV_H_
25#include <boost/functional/hash.hpp>
27#include "lib/exceptions.h"
28#include "lib/ordered_set.h"
44enum class Kind :
unsigned short { tagalong = 0, dark = 1, mocha = 2, normal = 3 };
46const Kind KINDS[] = {Kind::tagalong, Kind::dark, Kind::mocha, Kind::normal};
48const std::map<Kind, cstring> STR_OF_KIND = {{Kind::tagalong,
"tagalong"_cs},
49 {Kind::dark,
"dark"_cs},
50 {Kind::mocha,
"mocha"_cs},
51 {Kind::normal,
"normal"_cs}};
54enum class Context :
unsigned short {
61inline std::vector<Context> all_contexts(
Kind kind) {
63 case PHV::Kind::normal:
64 return {Context::parde, Context::ixbar, Context::vliw, Context::vliw_set};
66 case PHV::Kind::tagalong:
67 return {Context::parde};
69 case PHV::Kind::mocha:
70 return {Context::parde, Context::ixbar, Context::vliw_set};
73 return {Context::vliw_set};
76 BUG(
"Unknown PHV container kind");
100 return (
size_t)left < (size_t)right;
103inline bool operator<=(
Kind left,
Kind right) {
return left == right || left < right; }
105inline bool operator>(
Kind left,
Kind right) {
return right < left; }
107inline bool operator>=(
Kind left,
Kind right) {
return left == right || left > right; }
110enum class Size :
unsigned short { null = 0, b8 = 8, b16 = 16, b32 = 32 };
112const Size SIZES[] = {Size::null, Size::b8, Size::b16, Size::b32};
134 Type() : kind_(Kind::normal), size_(Size::null) {}
136 Type(
const Type &t) : kind_(t.kind_), size_(t.size_) {}
139 Type(
const char *name,
bool abort_if_invalid =
true);
141 unsigned log2sz()
const;
142 Kind kind()
const {
return kind_; }
143 Size size()
const {
return size_; }
151 bool operator==(
Type c)
const {
return (kind_ == c.kind_) && (size_ == c.size_); }
153 bool operator!=(
Type c)
const {
return !(*
this == c); }
155 bool operator<(
Type c)
const {
156 if (kind_ < c.kind_)
return true;
157 if (c.kind_ < kind_)
return false;
158 if (size_ < c.size_)
return true;
159 if (size_ > c.size_)
return false;
163 friend size_t hash_value(
const Type &c) {
165 boost::hash_combine(h, c.kind_);
166 boost::hash_combine(h, c.size_);
170 bool valid()
const {
return size_ != Size::null; }
177 static constexpr unsigned MAX_INDEX = std::numeric_limits<unsigned>::max();
190 Container(
const char *name,
bool abort_if_invalid =
true);
196 size_t size()
const {
return size_t(type_.size()); }
197 unsigned log2sz()
const {
return type_.log2sz(); }
198 size_t msb()
const {
return size() - 1; }
199 size_t lsb()
const {
return 0; }
202 unsigned index()
const {
return index_; }
204 bool is(
PHV::Kind k)
const {
return k == type_.kind(); }
205 bool is(
PHV::Size sz)
const {
return sz == type_.size(); }
209 explicit operator bool()
const {
return type_.valid(); }
212 if (index_ != MAX_INDEX) ++index_;
220 bool operator==(
Container c)
const {
return type_ == c.type_ && index_ == c.index_; }
221 bool operator!=(
Container c)
const {
return !(*
this == c); }
223 if (type_ < c.type_)
return true;
224 if (c.type_ < type_)
return false;
225 if (index_ < c.index_)
return true;
226 if (c.index_ < index_)
return false;
230 friend size_t hash_value(
const Container &c) {
232 boost::hash_combine(h, c.type_);
233 boost::hash_combine(h, c.index_);
252 enum use_t { READ = 1, WRITE = 2, READWRITE = READ | WRITE, LIVE = 4 };
259 BUG_CHECK(u == READ || u == WRITE || u == READWRITE || u == LIVE,
260 "Invalid value %1% used to create a FieldUse object. Valid values are "
261 "1: READ, 2: WRITE, 3: READWRITE, 4: LIVE",
266 bool isRead()
const {
return use_ & READ; }
267 bool isOnlyReadAndNotLive()
const {
return use_ == READ; }
268 bool isOnlyWriteAndNotLive()
const {
return use_ == WRITE; }
269 bool isWrite()
const {
return use_ & WRITE; }
270 bool isLive()
const {
return use_ & LIVE; }
271 bool isReadWrite()
const {
return use_ & READWRITE; }
272 bool isReadAndWrite()
const {
return use_ == READWRITE; }
274 bool operator==(
FieldUse u)
const {
return use_ == u.use_; }
275 bool operator!=(
FieldUse u)
const {
return !(*
this == u); }
276 bool operator<(
FieldUse u)
const {
return use_ < u.use_; }
277 bool operator>(
FieldUse u)
const {
return use_ > u.use_; }
278 bool operator<=(
FieldUse u)
const {
return use_ <= u.use_; }
279 bool operator>=(
FieldUse u)
const {
return use_ >= u.use_; }
280 explicit operator bool()
const {
return use_ == 0; }
284 ru.use_ = use_ | u.use_;
285 BUG_CHECK(ru.use_ <= (READWRITE | LIVE),
"invalid use of FieldUse %1%", ru.use_);
291 BUG_CHECK(use_ <= (READWRITE | LIVE),
"invalid use of FieldUse%1%", use_);
297 ru.use_ = use_ & u.use_;
298 BUG_CHECK(ru.use_ <= (READWRITE | LIVE),
"invalid use of FieldUse%1%", ru.use_);
302 cstring toString(
unsigned dark = 0)
const;
306using StageAndAccess = std::pair<int, FieldUse>;
310 StageAndAccess start;
312 LiveRange(
const StageAndAccess &start,
const StageAndAccess &end) : start(start), end(end) {}
313 bool is_disjoint(
const LiveRange &other)
const;
315 void extend(
const StageAndAccess &access);
316 bool operator<(
const LiveRange &other)
const {
317 if (start.first != other.start.first)
318 return start.first < other.start.first;
320 return end.first < other.end.first;
322 bool operator==(
const LiveRange &other)
const {
323 return start == other.start && end == other.end;
327std::ostream &operator<<(std::ostream &out,
const PHV::Kind k);
328std::ostream &operator<<(std::ostream &out,
const PHV::Size sz);
329std::ostream &operator<<(std::ostream &out,
const PHV::Type t);
330std::ostream &operator<<(std::ostream &out,
const PHV::Container c);
332std::ostream &operator<<(std::ostream &out,
const PHV::FieldUse u);
333std::ostream &operator<<(std::ostream &out,
const StageAndAccess &s);
334std::ostream &operator<<(std::ostream &out,
const LiveRange &s);
Definition json_generator.h:36
Definition json_loader.h:38
Definition ordered_set.h:32
void toJSON(P4::JSONGenerator &json) const
JSON serialization/deserialization.
Definition phv.cpp:162
Container()
Definition phv.h:187
Container(PHV::Type t, unsigned index)
Definition phv.h:194
cstring toString() const
Definition phv.cpp:156
cstring toString() const
Definition phv.cpp:137
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
The namespace encapsulating PHV-related stuff.
Definition gateway.h:32
Size
all possible PHV container sizes in BFN devices
Definition phv.h:110