Skip to content

Commit

Permalink
[mlir][PDLL] Allow numeric result indexing for unregistered op
Browse files Browse the repository at this point in the history
If we don't specify the result index while matching operand with the
result of certain operation, it's supposed to match all the results of
the operation with the operand. For registered op, it's easy to do that
by either indexing with number or name. For unregistered op, this commit
enables the numeric result indexing for this use case.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D126330
  • Loading branch information
ChiaHungDuan committed May 25, 2022
1 parent ef1ea5a commit c088fbe
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 5 deletions.
17 changes: 14 additions & 3 deletions mlir/docs/PDLL.md
Expand Up @@ -700,9 +700,9 @@ let inputOp = op<my_dialect.input_op>(resultOp.result, resultOp.0);
```

Along with result name access, variables of `Op` type may implicitly convert to
`Value` or `ValueRange`. These variables are converted to `Value` when they are
known (via ODS) to only have one result, in all other cases they convert to
`ValueRange`:
`Value` or `ValueRange`. If these variables are registered (has ODS entry), they
are converted to `Value` when they are known to only have one result, otherwise
they will be converted to `ValueRange`:

```pdll
// `resultOp` may also convert implicitly to a Value for use in `inputOp`:
Expand All @@ -713,6 +713,17 @@ let inputOp = op<my_dialect.input_op>(resultOp);
let inputOp = op<my_dialect.input_op>(op<my_dialect.result_op>);
```

#### Unregistered Operations

A variable of unregistered op is still available for numeric result indexing.
Given that we don't have knowledge of its result groups, numeric indexing
returns a Value corresponding to the individual result at the given index.

```pdll
// Use the index `0` to refer to the first result value of the unregistered op.
let inputOp = op<my_dialect.input_op>(op<my_dialect.unregistered_op>.0);
```

### Attribute Expression

An attribute expression represents a literal MLIR attribute. It allows for
Expand Down
10 changes: 9 additions & 1 deletion mlir/lib/Tools/PDLL/CodeGen/MLIRGen.cpp
Expand Up @@ -444,7 +444,15 @@ Value CodeGen::genExprImpl(const ast::MemberAccessExpr *expr) {

assert(opType.getName() && "expected valid operation name");
const ods::Operation *odsOp = odsContext.lookupOperation(*opType.getName());
assert(odsOp && "expected valid ODS operation information");

if (!odsOp) {
assert(llvm::isDigit(name[0]) && "unregistered op only allows numeric indexing");
unsigned resultIndex;
name.getAsInteger(/*Radix=*/10, resultIndex);
IntegerAttr index = builder.getI32IntegerAttr(resultIndex);
return builder.create<pdl::ResultOp>(loc, genType(expr->getType()),
parentExprs[0], index);
}

// Find the result with the member name or by index.
ArrayRef<ods::OperandOrResult> results = odsOp->getResults();
Expand Down
5 changes: 4 additions & 1 deletion mlir/lib/Tools/PDLL/Parser/Parser.cpp
Expand Up @@ -2683,8 +2683,11 @@ FailureOr<ast::Type> Parser::validateMemberAccess(ast::Expr *parentExpr,
});
if (it != results.end())
return it->isVariadic() ? valueRangeTy : valueTy;
} else if (llvm::isDigit(name[0])) {
// Allow unchecked numeric indexing of the results of unregistered
// operations. It returns a single value.
return valueTy;
}

} else if (auto tupleType = parentType.dyn_cast<ast::TupleType>()) {
// Handle indexed results.
unsigned index = 0;
Expand Down
13 changes: 13 additions & 0 deletions mlir/test/mlir-pdll/CodeGen/MLIR/expr.pdll
Expand Up @@ -55,6 +55,19 @@ Pattern OpAllResultMemberAccess {

// -----

// Handle result indexing on unregistered op.
// CHECK: pdl.pattern @UnregisteredOpResultIndexing
// CHECK: %[[BAR_OP:.*]] = operation "my_dialect.unregistered_bar"
// CHECK: %[[BAR_RES:.*]] = result 0 of %[[BAR_OP]]
// CHECK: operation "my_dialect.unregistered_foo"(%[[BAR_RES]] : !pdl.value)
Pattern UnregisteredOpResultIndexing {
let bar : Op<my_dialect.unregistered_bar>;
let op = op<my_dialect.unregistered_foo>(bar.0);
erase op;
}

// -----

// Handle implicit "named" operation results access.

#include "include/ops.td"
Expand Down
20 changes: 20 additions & 0 deletions mlir/test/mlir-pdll/Parser/expr.pdll
Expand Up @@ -90,6 +90,26 @@ Pattern {

// -----

// CHECK: Module
// CHECK: `-VariableDecl {{.*}} Name<op> Type<Op<my_dialect.unregistered_foo>>
// CHECK: `-OperationExpr {{.*}} Type<Op<my_dialect.unregistered_foo>>
// CHECK: `-OpNameDecl {{.*}} Name<my_dialect.unregistered_foo>
// CHECK: `Operands`
// CHECK: `-MemberAccessExpr {{.*}} Member<0> Type<Value>
// CHECK: `-OperationExpr {{.*}} Type<Op<my_dialect.unregistered_bar>>
// CHECK: `-OpNameDecl {{.*}} Name<my_dialect.unregistered_bar>
// CHECK: `Operands`
// CHECK: `-DeclRefExpr {{.*}} Type<ValueRange>
// CHECK: `-VariableDecl {{.*}} Name<_> Type<ValueRange>
// CHECK: `Constraints`
// CHECK: `-ValueRangeConstraintDecl
Pattern {
let op = op<my_dialect.unregistered_foo>(op<my_dialect.unregistered_bar>.0);
erase op;
}

// -----

//===----------------------------------------------------------------------===//
// OperationExpr
//===----------------------------------------------------------------------===//
Expand Down

0 comments on commit c088fbe

Please sign in to comment.