Skip to content

Commit

Permalink
Add parser apply operator. Few fixes while there
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Korobeynikov <anton@korobeynikov.info>
  • Loading branch information
asl committed Feb 28, 2025
1 parent 9b489b1 commit 7c2cbcf
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 13 deletions.
54 changes: 51 additions & 3 deletions include/p4mlir/Dialect/P4HIR/P4HIR_Ops.td
Original file line number Diff line number Diff line change
Expand Up @@ -1002,13 +1002,16 @@ def InstantiateOp : P4HIR_Op<"instantiate",
DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> {
let summary = "constructor call operation";
let description = [{
Instantiate P4 object: extern, parser, control or package/
Instantiate P4 object: extern, parser, control or package.

Example:

```mlir
// Direct call of function
%2 = p4hir.call @my_add(%0, %1) : (!p4hir.bit<8>, !p4hir.bit<8>) -> !p4hir.bit<8>
// Instantiate a subparser
%sp = p4hir.instantiate @subparser() as "sp" : () -> !p4hir.parser<"subparser", (!empty)>
// Instantiate a subparser with ctor parameters
%false = p4hir.const #false
%sp2 = p4hir.instantiate @subparser2(%false) as "sp2" : (!p4hir.bool) -> !p4hir.parser<"subparser2", (!empty)>
...
```
}];
Expand Down Expand Up @@ -1054,6 +1057,51 @@ def InstantiateOp : P4HIR_Op<"instantiate",
}];
}

def ApplyOp : P4HIR_Op<"apply",
[NoRegionArguments, CallOpInterface,
//DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>
TypesMatchWith<
"the apply type of the object matches the types of operands",
"callee", "arg_operands", "cast<P4HIR::ParserType>($_self).getInputs()">,
]> {
let summary = "apply operation";
let description = [{
Applies P4 parser, table or control

Example:

```mlir
// Application of a subparser
%sp = p4hir.instantiate @subparser() as "sp" : () -> !p4hir.parser<"subparser", ()>
p4hir.apply %sp() : !p4hir.parser<"subparser", ()>
...
```
}];

// TODO: Refine result types, refine parameter type (must be constants!)
let results = (outs);
let arguments = (ins P4ObjectType:$callee, Variadic<AnyType>:$arg_operands);

// TODO: Add verifier
let hasVerifier = 0;

let extraClassDeclaration = [{
/// Return the callee of this operation.
mlir::CallInterfaceCallable getCallableForCallee() {
return getCallee();
}

/// Set the callee for this operation.
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
getCalleeMutable().assign(callee.get<mlir::Value>());
}
}];

let assemblyFormat = [{
$callee `(` $arg_operands `)` attr-dict `:` type($callee)
}];
}


include "p4mlir/Dialect/P4HIR/P4HIR_ParserOps.td"

Expand Down
26 changes: 21 additions & 5 deletions test/Translate/Parser/subparser.p4
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,39 @@ parser subparser2(in empty e)(bool ctorArg) {
}
}

// CHECK-LABEL: p4hir.parser @p
// CHECK: p4hir.instantiate @subparser() as "sp" : () -> !p4hir.parser<"subparser", (!empty)>
// CHECK: %[[false:.*]] = p4hir.const #false
// CHECK: p4hir.instantiate @subparser2(%[[false]]) as "sp2" : (!p4hir.bool) -> !p4hir.parser<"subparser2", (!empty)>
parser subparser3(inout int<10> s, out bool matched)() {
state start {
transition accept;
}
}

// CHECK-LABEL: p4hir.parser @p(%arg0: !empty, %arg1: !i10i)()
parser p(in empty e, in int<10> sinit) {
int<10> s = sinit;
subparser() sp;
subparser2(false) sp2;
subparser3() sp3;
// CHECK: %[[sp:.*]] = p4hir.instantiate @subparser() as "sp" : () -> !p4hir.parser<"subparser", (!empty)>
// CHECK: %[[false:.*]] = p4hir.const #false
// CHECK: %[[sp2:.*]] = p4hir.instantiate @subparser2(%[[false]]) as "sp2" : (!p4hir.bool) -> !p4hir.parser<"subparser2", (!empty)>
// CHECK: %[[sp3:.*]] = p4hir.instantiate @subparser3() as "sp3" : () -> !p4hir.parser<"subparser3", (!p4hir.ref<!i10i>, !p4hir.ref<!p4hir.bool>)>

state start {
s = 1;
sp.apply(e);
// CHECK: p4hir.apply %[[sp]](%arg0) : !p4hir.parser<"subparser", (!empty)>
transition next;
}

state next {
s = 2;
sp2.apply(e);
// CHECK: p4hir.apply %[[sp2]](%arg0) : !p4hir.parser<"subparser2", (!empty)>
// CHECK: p4hir.scope
// CHECK: p4hir.apply %[[sp3]](%s_inout_arg, %matched_out_arg) : !p4hir.parser<"subparser3", (!p4hir.ref<!i10i>, !p4hir.ref<!p4hir.bool>)>
bool matched = false;
sp3.apply(s, matched);

transition accept;
}

Expand Down
21 changes: 16 additions & 5 deletions tools/p4mlir-translate/translate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,10 @@ bool P4TypeConverter::preorder(const P4::IR::Type_Parser *type) {
ConversionTracer trace("TypeConverting ", type);

llvm::SmallVector<mlir::Type, 4> argTypes;
for (const auto *p : type->getApplyParameters()->parameters)
argTypes.emplace_back(convert(p->type));
for (const auto *p : type->getApplyParameters()->parameters) {
mlir::Type type = convert(p->type);
argTypes.push_back(p->hasOut() ? P4HIR::ReferenceType::get(type) : type);
}

auto mlirType = P4HIR::ParserType::get(converter.context(), type->name.string_view(), argTypes);
return setType(type, mlirType);
Expand Down Expand Up @@ -1340,6 +1342,14 @@ bool P4HIRConverter::preorder(const P4::IR::MethodCallExpression *mce) {
BUG_CHECK(fSym, "expected reference function to be converted: %1%", fCall->method);

callResult = b.create<P4HIR::CallOp>(loc, fSym, callResultType, operands).getResult();
} else if (const auto *aCall = instance->to<P4::ApplyMethod>()) {
LOG4("resolved as apply");
// Apply of something instantiated
if (auto *decl = aCall->object->to<P4::IR::Declaration_Instance>()) {
auto val = getValue(decl);
b.create<P4HIR::ApplyOp>(loc, val, operands);
} else
BUG("Unsuported apply: %1%", aCall->object);
} else {
BUG("unsupported call type: %1%", mce);
}
Expand Down Expand Up @@ -1699,9 +1709,10 @@ bool P4HIRConverter::preorder(const P4::IR::Declaration_Instance *decl) {
auto parserSym = p4Symbols.lookup(parser);
BUG_CHECK(parserSym, "expected reference parser to be converted: %1%", dbp(parser));

builder.create<P4HIR::InstantiateOp>(getLoc(builder, decl), resultType,
parserSym.getRootReference(), operands,
builder.getStringAttr(decl->name.string_view()));
auto instance = builder.create<P4HIR::InstantiateOp>(
getLoc(builder, decl), resultType, parserSym.getRootReference(), operands,
builder.getStringAttr(decl->name.string_view()));
setValue(decl, instance.getResult());
} else {
BUG("unsupported instance type: %1%", decl);
}
Expand Down

0 comments on commit 7c2cbcf

Please sign in to comment.