Skip to content

Commit

Permalink
New syntax for vector literals
Browse files Browse the repository at this point in the history
Signed-off-by: Mihai Budiu <mbudiu@vmware.com>
  • Loading branch information
Mihai Budiu committed Sep 20, 2022
1 parent b19b881 commit 994fa25
Show file tree
Hide file tree
Showing 25 changed files with 188 additions and 31 deletions.
1 change: 1 addition & 0 deletions backends/p4test/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ MidEnd::MidEnd(CompilerOptions& options, std::ostream* outStream) {
if (options.excludeMidendPasses) {
removePasses(options.passesToExcludeMidend);
}
addDebugHooks(hooks, true);
}

} // namespace P4Test
4 changes: 4 additions & 0 deletions backends/p4test/midend.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,21 @@ limitations under the License.
#include "ir/ir.h"
#include "frontends/common/options.h"
#include "frontends/p4/evaluator/evaluator.h"
#include "frontends/common/options.h"

namespace P4Test {

class MidEnd : public PassManager {
std::vector<DebugHook> hooks;
public:
P4::ReferenceMap refMap;
P4::TypeMap typeMap;
IR::ToplevelBlock *toplevel = nullptr;

void addDebugHook(DebugHook hook) { hooks.push_back(hook); }
explicit MidEnd(CompilerOptions& options, std::ostream* outStream = nullptr);
IR::ToplevelBlock* process(const IR::P4Program *&program) {
addDebugHooks(hooks, true);
program = program->apply(*this);
return toplevel; }
};
Expand Down
25 changes: 18 additions & 7 deletions frontends/p4/toP4/toP4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,16 +851,27 @@ bool ToP4::preorder(const IR::ListExpression* e) {
}

bool ToP4::preorder(const IR::VectorExpression* e) {
builder.append("[");
visit(e->elementType->getP4Type());
builder.append("; ");
setVecSep(", ");
if (expressionPrecedence > DBPrint::Prec_Prefix)
builder.append("(");
if (e->elementType != nullptr) {
builder.append("(Vector<");
visit(e->elementType->getP4Type());
builder.append(">)");
}
builder.append("{");
int prec = expressionPrecedence;
expressionPrecedence = DBPrint::Prec_Low;
preorder(&e->components);
bool first = true;
for (auto c : e->components) {
if (!first)
builder.append(",");
first = false;
visit(c);
}
expressionPrecedence = prec;
doneVec();
builder.append("]");
builder.append("}");
if (expressionPrecedence > DBPrint::Prec_Prefix)
builder.append(")");
return false;
}

Expand Down
37 changes: 37 additions & 0 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2750,25 +2750,36 @@ const IR::Node* TypeInference::postorder(IR::Cast* expression) {
se->srcInfo, type, se->components);
auto result = postorder(sie); // may insert casts
setType(result, st);
if (isCompileTimeConstant(se)) {
setCompileTimeConstant(result->to<IR::Expression>());
setCompileTimeConstant(getOriginal<IR::Expression>());
}
return result;
} else {
typeError("%1%: cast not supported", expression->destType);
return expression;
}
} else if (auto le = expression->expr->to<IR::ListExpression>()) {
if (st->fields.size() == le->size()) {
bool isConstant = true;
IR::IndexedVector<IR::NamedExpression> vec;
for (size_t i = 0; i < st->fields.size(); i++) {
auto fieldI = st->fields.at(i);
auto compI = le->components.at(i);
auto src = assignment(expression, fieldI->type, compI);
if (!isCompileTimeConstant(src))
isConstant = false;
vec.push_back(new IR::NamedExpression(fieldI->name, src));
}
auto setype = castType->getP4Type();
setType(setype, new IR::Type_Type(st));
auto result = new IR::StructExpression(
le->srcInfo, setype, setype, vec);
setType(result, st);
if (isConstant) {
setCompileTimeConstant(result);
setCompileTimeConstant(getOriginal<IR::Expression>());
}
return result;
} else {
typeError("%1%: destination type expects %2% fields, but source only has %3%",
Expand All @@ -2777,6 +2788,32 @@ const IR::Node* TypeInference::postorder(IR::Cast* expression) {
}
}
}
if (auto vt = concreteType->to<IR::Type_Vector>()) {
auto vecElementType = vt->elementType;
if (auto le = expression->expr->to<IR::ListExpression>()) {
IR::Vector<IR::Expression> vec;
bool isConstant = true;
for (size_t i = 0; i < le->size(); i++) {
auto compI = le->components.at(i);
auto src = assignment(expression, vecElementType, compI);
if (!isCompileTimeConstant(src))
isConstant = false;
vec.push_back(src);
}
auto vecType = castType->getP4Type();
setType(vecType, new IR::Type_Type(vt));
auto result = new IR::VectorExpression(le->srcInfo, vec, vecElementType);
setType(result, vt);
if (isConstant) {
setCompileTimeConstant(result);
setCompileTimeConstant(getOriginal<IR::Expression>());
}
return result;
} else {
typeError("%1%: casts to vector not supported", expression);
return expression;
}
}

if (!castType->is<IR::Type_Bits>() &&
!castType->is<IR::Type_Boolean>() &&
Expand Down
1 change: 0 additions & 1 deletion frontends/parsers/p4/p4parser.ypp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,6 @@ expression
| expression "[" expression "]" { $$ = new IR::ArrayIndex(@1 + @4, $1, $3); }
| expression "[" expression ":" expression "]" { $$ = new IR::Slice(@1 + @6, $1, $3, $5); }
| "{" expressionList "}" { $$ = new IR::ListExpression(@1 + @3, *$2); }
| "[" typeRef ";" expressionList "]" { $$ = new IR::VectorExpression(@1 + @5, *$4, $2); }
| "{" kvList "}" { $$ = new IR::StructExpression(
@1 + @3, IR::Type::Unknown::get(), (IR::Type_Name*)nullptr, *$2); }
| "(" expression ")" { $$ = $2; }
Expand Down
8 changes: 7 additions & 1 deletion midend/eliminateTuples.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ReplacementMap {
* the tuple is left unchanged, as below:
* struct S<T> { tuple<T> x; }
* This decision may need to be revisited in the future.
* Do not replace types within vectors either.
*
* @pre none
* @post ensure all tuples are replaced with struct.
Expand All @@ -78,6 +79,7 @@ class DoReplaceTuples final : public Transform {
DoReplaceTuples(ReferenceMap* refMap, TypeMap* typeMap) :
repl(new ReplacementMap(refMap, typeMap))
{ setName("DoReplaceTuples"); }
const IR::Node* skip(const IR::Node* node) { prune(); return node; }
const IR::Node* postorder(IR::Type_BaseList* type) override;
const IR::Node* insertReplacements(const IR::Node* before);
const IR::Node* postorder(IR::Type_Struct* type) override
Expand All @@ -93,14 +95,18 @@ class DoReplaceTuples final : public Transform {
{ return insertReplacements(control); }
const IR::Node* postorder(IR::Method* method) override
{ return insertReplacements(method); }
const IR::Node* preorder(IR::VectorExpression* expression) override
{ return skip(expression); }
const IR::Node* postorder(IR::Type_Extern* ext) override
{ return insertReplacements(ext); }
const IR::Node* postorder(IR::Declaration_Instance* decl) override
{ return insertReplacements(decl); }
const IR::Node* preorder(IR::P4ValueSet* set) override
// Disable substitution of type parameters for value sets.
// We want to keep these as tuples.
{ prune(); return set; }
{ return skip(set); }
const IR::Node* preorder(IR::Type_Vector* vector) override
{ return skip(vector); }
};

class EliminateTuples final : public PassManager {
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_errors/vector-error.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
E([bit<16>; 2, 3, 4]) e;
E((Vector<bit<16>>){2, 3, 4}) e;
apply {
e.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_errors_outputs/vector-error.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
E([ bit<16>; 2, 3, 4 ]) e;
E((Vector<bit<16>>){ 2, 3, 4 }) e;
apply {
e.run();
}
Expand Down
20 changes: 10 additions & 10 deletions testdata/p4_16_errors_outputs/vector-error.p4-stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
vector-error.p4(9): [--Werror=type-error] error: e
E([bit<16>; 2, 3, 4]) e;
^
E((Vector<bit<16>>){2, 3, 4}) e;
^
---- Actual error:
vector-error.p4(9): Cannot unify type 'Vector<bit<16>>' with type 'Vector<bit<32>>'
E([bit<16>; 2, 3, 4]) e;
^^^^^^^^^^^^^^^^^^
E((Vector<bit<16>>){2, 3, 4}) e;
^^^^^^^^^^^^^^^
vector-error.p4(4)
E(Vector<bit<32>> data);
^^^^^^^^^^^^^^^
---- Originating from:
vector-error.p4(9): Type of argument 'VectorExpression' (Vector<bit<16>>) does not match type of parameter 'data' (Vector<bit<32>>)
E([bit<16>; 2, 3, 4]) e;
^^^^^^^^^^^^^^^^^^
E((Vector<bit<16>>){2, 3, 4}) e;
^^^^^^^^^^^^^^^^^^^^^^^^^^
vector-error.p4(9)
E([bit<16>; 2, 3, 4]) e;
^^^^^^^^^^^^^^^^^^
E((Vector<bit<16>>){2, 3, 4}) e;
^^^^^^^^^^^^^^^
vector-error.p4(4)
E(Vector<bit<32>> data);
^^^^
Expand All @@ -23,8 +23,8 @@ vector-error.p4(4)
^^^^^^^^^^^^^^^
---- Originating from:
vector-error.p4(9): Constructor invocation <Method call> does not match constructor declaration E
E([bit<16>; 2, 3, 4]) e;
^
E((Vector<bit<16>>){2, 3, 4}) e;
^
vector-error.p4(4)
E(Vector<bit<32>> data);
^
2 changes: 1 addition & 1 deletion testdata/p4_16_samples/vector.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
E([bit<32>; 2, 3, 4]) e;
E((Vector<bit<32>>){2, 3, 4}) e;
apply {
e.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples/vector1.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern E {
}

control c() {
E([S; {2, 3}, {4, 5}]) e;
E((Vector<S>){{2, 3}, {4, 5}}) e;
apply {
e.run();
}
Expand Down
18 changes: 18 additions & 0 deletions testdata/p4_16_samples/vector2.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <core.p4>

extern E<T, S> {
E(Vector<tuple<T, S>> data);
void run();
}

control c() {
E<bit<32>, bit<16>>((Vector<tuple<bit<32>, bit<16>>>){{2, 3}, {4, 5}}) e;
apply {
e.run();
}
}

control C();
package top(C _c);

top(c()) main;
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector-first.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
E([ bit<32>; 32w2, 32w3, 32w4 ]) e;
E((Vector<bit<32>>){32w2,32w3,32w4}) e;
apply {
e.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector-frontend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
@name("c.e") E([ bit<32>; 32w2, 32w3, 32w4 ]) e_0;
@name("c.e") E((Vector<bit<32>>){32w2,32w3,32w4}) e_0;
apply {
e_0.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector-midend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
@name("c.e") E([ bit<32>; 32w2, 32w3, 32w4 ]) e_0;
@name("c.e") E((Vector<bit<32>>){32w2,32w3,32w4}) e_0;
@hidden action vector11() {
e_0.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern E {
}

control c() {
E([ bit<32>; 2, 3, 4 ]) e;
E((Vector<bit<32>>){ 2, 3, 4 }) e;
apply {
e.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector1-first.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern E {
}

control c() {
E([S; { 32w2, 32w3 }, { 32w4, 32w5 }]) e;
E((Vector<S>){(S){a = 32w2,b = 32w3},(S){a = 32w4,b = 32w5}}) e;
apply {
e.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector1-frontend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern E {
}

control c() {
@name("c.e") E([S; { 32w2, 32w3 }, { 32w4, 32w5 }]) e_0;
@name("c.e") E((Vector<S>){(S){a = 32w2,b = 32w3},(S){a = 32w4,b = 32w5}}) e_0;
apply {
e_0.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector1-midend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern E {
}

control c() {
@name("c.e") E([S; { 32w2, 32w3 }, { 32w4, 32w5 }]) e_0;
@name("c.e") E((Vector<S>){(S){a = 32w2,b = 32w3},(S){a = 32w4,b = 32w5}}) e_0;
@hidden action vector1l16() {
e_0.run();
}
Expand Down
2 changes: 1 addition & 1 deletion testdata/p4_16_samples_outputs/vector1.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern E {
}

control c() {
E([S; { 2, 3 }, { 4, 5 }]) e;
E((Vector<S>){ { 2, 3 }, { 4, 5 } }) e;
apply {
e.run();
}
Expand Down
18 changes: 18 additions & 0 deletions testdata/p4_16_samples_outputs/vector2-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <core.p4>

extern E<T, S> {
E(Vector<tuple<T, S>> data);
void run();
}

control c() {
E<bit<32>, bit<16>>((Vector<tuple<bit<32>, bit<16>>>){{ 32w2, 16w3 },{ 32w4, 16w5 }}) e;
apply {
e.run();
}
}

control C();
package top(C _c);
top(c()) main;

18 changes: 18 additions & 0 deletions testdata/p4_16_samples_outputs/vector2-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <core.p4>

extern E<T, S> {
E(Vector<tuple<T, S>> data);
void run();
}

control c() {
@name("c.e") E<bit<32>, bit<16>>((Vector<tuple<bit<32>, bit<16>>>){{ 32w2, 16w3 },{ 32w4, 16w5 }}) e_0;
apply {
e_0.run();
}
}

control C();
package top(C _c);
top(c()) main;

Loading

0 comments on commit 994fa25

Please sign in to comment.