Skip to content

Commit dbc1283

Browse files
mouse-mtvbnogueira
authored andcommitted
Add new methods to IR types to support varbit
Add the following new methods: - min_width_bits: Determines the minumum type's bit size - max_width_bits: Determines the maximum type's bit size - min_or_fixed_width_bits: Same as min_width_bits but also works for non-variable types - max_or_fixed_width_bits: Same as max_width_bits but also works for non-variable types - variable: Tells whether the type has variable length Signed-off-by: Mouse <[email protected]>
1 parent 8b6de3c commit dbc1283

File tree

2 files changed

+98
-6
lines changed

2 files changed

+98
-6
lines changed

ir/base.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ abstract Type {
4040
#end
4141
/// Well-defined only for types with fixed width
4242
virtual int width_bits() const { BUG("width_bits() on type with unknown size: %1%", this); }
43+
virtual int min_width_bits() const { BUG("min_width_bits() on type of unknown size: %1%", this); }
44+
virtual int max_width_bits() const { BUG("max_width_bits() on type of unknown size: %1%", this); }
45+
virtual int min_or_fixed_width_bits() const { BUG("min_or_fixed_width_bits() on type of unknown size: %1%", this); }
46+
virtual int max_or_fixed_width_bits() const { BUG("max_or_fixed_width_bits() on type of unknown size: %1%", this); }
47+
virtual bool variable() const { return false; }
4348
/// When possible returns the corresponding type that can be inserted
4449
/// in a P4 program; may return a Type_Name
4550
virtual const Type* getP4Type() const = 0;
@@ -118,6 +123,7 @@ interface IContainer : IMayBeGenericType, IDeclaration, IFunctional {
118123
/// (called base type in the spec)
119124
abstract Type_Base : Type {
120125
const Type* getP4Type() const override { return this; }
126+
virtual bool variable() const override { return false; }
121127
}
122128

123129
/// This is needed by Expression
@@ -130,7 +136,6 @@ class Type_Unknown : Type_Base {
130136

131137
/// A statement or a declaration
132138
abstract StatOrDecl {}
133-
134139
/// Two declarations with the same name are not necessarily the same declaration.
135140
/// That's why declid is used to distinguish them.
136141
abstract Declaration : StatOrDecl, IDeclaration {

ir/type.def

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class Type_Boolean : Type_Base {
147147
static Type_Boolean get();
148148
static Type_Boolean get(const Util::SourceInfo &si);
149149
int width_bits() const override { return 1; }
150+
int min_width_bits() const override { BUG("min_width_bits() on fixed-width type: %1%", this); }
151+
int max_width_bits() const override { BUG("max_width_bits() on fixed-width type: %1%", this); }
152+
int min_or_fixed_width_bits() const override { return width_bits(); }
153+
int max_or_fixed_width_bits() const override { return width_bits(); }
150154
toString{ return "bool"_cs; }
151155
dbprint { out << "bool"; }
152156
}
@@ -191,6 +195,8 @@ class Type_Bits : Type_Base {
191195
static Type_Bits get(int sz, bool isSigned = false);
192196
inline cstring baseName() const { return isSigned ? "int"_cs : "bit"_cs; }
193197
int width_bits() const override { return size; }
198+
int min_width_bits() const override { BUG("min_width_bits() on fixed-width type: %1%", this); }
199+
int max_width_bits() const override { BUG("max_width_bits() on fixed-width type: %1%", this); }
194200

195201
toString{ return absl::StrCat(baseName(), "<", size, ">"); }
196202
dbprint { out << toString(); }
@@ -217,6 +223,11 @@ class Type_Varbits : Type_Base {
217223
toString{ return absl::StrCat("varbit<", size, ">"); }
218224
dbprint { out << "varbit<" << size << ">"; }
219225
int width_bits() const override { return size; }
226+
int min_width_bits() const override { return 0; }
227+
int max_width_bits() const override { return size; }
228+
int min_or_fixed_width_bits() const override { return min_width_bits(); }
229+
int max_or_fixed_width_bits() const override { return max_width_bits(); }
230+
virtual bool variable() const override { return true; }
220231
}
221232

222233
class Parameter : Declaration, IAnnotated {
@@ -306,6 +317,8 @@ class Type_InfInt : Type, ITypeVar {
306317
}
307318
const Type* getP4Type() const override { return this; }
308319
int width_bits() const override { return 0; }
320+
int min_width_bits() const override { BUG("min_width_bits() on unsized type: %1%", this); }
321+
int max_width_bits() const override { BUG("max_width_bits() on unsized type: %1%", this); }
309322
}
310323

311324
class Type_Dontcare : Type_Base {
@@ -430,12 +443,35 @@ abstract Type_StructLike : Type_Declaration, INestedNamespace, ISimpleNamespace,
430443
}
431444
return -1;
432445
}
446+
// Yeah, this is inefficient. "First make it work..."
447+
virtual bool variable() const override {
448+
for (auto f : fields) {
449+
if (f->type->variable()) return true;
450+
}
451+
return false;
452+
}
433453
int width_bits() const override {
434454
int rv = 0;
435455
for (auto f : fields) {
436456
rv += f->type->width_bits();
437457
}
438-
return rv; }
458+
return rv;
459+
}
460+
int min_width_bits() const override {
461+
int rv;
462+
rv = 0;
463+
for (auto f : fields) {
464+
rv += f->type->min_or_fixed_width_bits();
465+
}
466+
return rv;
467+
}
468+
int max_width_bits() const override {
469+
int rv = 0;
470+
for (auto f : fields) {
471+
rv += f->type->max_or_fixed_width_bits();
472+
}
473+
return rv;
474+
}
439475
IR::IDeclaration getDeclByName(cstring name) const override {
440476
return fields.getDeclaration(name); }
441477
IR::IDeclaration getDeclByName(std::string_view name) const override {
@@ -465,7 +501,24 @@ class Type_HeaderUnion : Type_StructLike {
465501
int rv = 0;
466502
for (auto f : fields)
467503
rv = std::max(rv, f->type->width_bits());
468-
return rv; }
504+
return rv;
505+
}
506+
int min_width_bits() const override {
507+
if (fields.empty())
508+
return 0;
509+
510+
auto first = fields.begin();
511+
int rv = (*first)->type->min_or_fixed_width_bits();
512+
for (auto f = fields.begin() + 1; f != fields.end(); f++)
513+
rv = std::min(rv, (*f)->type->min_or_fixed_width_bits());
514+
return rv;
515+
}
516+
int max_width_bits() const override {
517+
int rv = 0;
518+
for (auto f : fields)
519+
rv = std::max(rv, f->type->max_or_fixed_width_bits());
520+
return rv;
521+
}
469522
/// start offset of any field in a union is 0
470523
inline int getFieldBitOffset(cstring name) const {
471524
for (auto f : fields) {
@@ -492,7 +545,10 @@ class Type_Set : Type {
492545
int width_bits() const override {
493546
/// returning the width of the set elements, not the set itself, which doesn't
494547
/// really have a sensible size
495-
return elementType->width_bits(); }
548+
return elementType->width_bits();
549+
}
550+
int min_width_bits() const override { return elementType->min_width_bits(); }
551+
int max_width_bits() const override { return elementType->max_width_bits(); }
496552
}
497553

498554
interface Type_Indexed {
@@ -511,10 +567,25 @@ abstract Type_BaseList : Type, Type_Indexed {
511567
int width_bits() const override {
512568
/// returning sum of the width of the elements
513569
int rv = 0;
514-
for (auto f : components) {
570+
for (auto f : components)
515571
rv += f->width_bits();
572+
573+
return rv;
574+
}
575+
int min_width_bits() const override {
576+
int rv = 0;
577+
for (auto f : components) {
578+
rv += f->min_or_fixed_width_bits();
516579
}
517-
return rv; }
580+
return rv;
581+
}
582+
int max_width_bits() const override {
583+
int rv = 0;
584+
for (auto f : components) {
585+
rv += f->max_or_fixed_width_bits();
586+
}
587+
return rv;
588+
}
518589
cstring asString(const char* name) const {
519590
return
520591
absl::StrCat(name,
@@ -615,6 +686,14 @@ class Type_Name : Type {
615686
BUG("Type_Name is not a canonical type, use getTypeType()?");
616687
return 0;
617688
}
689+
int min_width_bits() const override {
690+
BUG("Type_Name is not a canonical type, use getTypeType()?");
691+
return 0;
692+
}
693+
int max_width_bits() const override {
694+
BUG("Type_Name is not a canonical type, use getTypeType()?");
695+
return 0;
696+
}
618697
}
619698

620699
class Type_Array : Type_Indexed, Type {
@@ -639,6 +718,8 @@ class Type_Array : Type_Indexed, Type {
639718
const Type* getP4Type() const override
640719
{ return new IR::Type_Array(srcInfo, elementType->getP4Type(), size); }
641720
int width_bits() const override { return getSize() * elementType->width_bits(); }
721+
int min_width_bits() const override { BUG("min_width_bits on a stack: %1%",this); }
722+
int max_width_bits() const override { BUG("max_width_bits on a stack: %1%",this); }
642723
}
643724

644725
/** Given a declaration
@@ -745,6 +826,8 @@ class Type_SerEnum : Type_Declaration, ISimpleNamespace, IAnnotated {
745826
#nodbprint
746827
validate{ members.check_null(); }
747828
int width_bits() const override { return type->width_bits(); }
829+
int min_width_bits() const override { return type->min_width_bits(); }
830+
int max_width_bits() const override { return type->max_width_bits(); }
748831
}
749832

750833
class Type_Table : Type, IApply {
@@ -860,6 +943,8 @@ class Type_Typedef : Type_Declaration, IAnnotated {
860943
optional inline Vector<Annotation> annotations;
861944
Type type;
862945
int width_bits() const override { return type->width_bits(); }
946+
int min_width_bits() const override { return type->min_width_bits(); }
947+
int max_width_bits() const override { return type->max_width_bits(); }
863948
const Vector<Annotation> &getAnnotations() const override { return annotations; }
864949
Vector<Annotation> &getAnnotations() override { return annotations; }
865950
#nodbprint
@@ -874,6 +959,8 @@ class Type_Newtype : Type_Declaration, IAnnotated {
874959
optional inline Vector<Annotation> annotations;
875960
Type type;
876961
int width_bits() const override { return type->width_bits(); }
962+
int min_width_bits() const override { return type->min_width_bits(); }
963+
int max_width_bits() const override { return type->max_width_bits(); }
877964
const Vector<Annotation> &getAnnotations() const override { return annotations; }
878965
Vector<Annotation> &getAnnotations() override { return annotations; }
879966
#nodbprint

0 commit comments

Comments
 (0)