Skip to content

Commit

Permalink
[mlir][PDL] Add a PDL Interpreter Dialect
Browse files Browse the repository at this point in the history
The PDL Interpreter dialect provides a lower level abstraction compared to the PDL dialect, and is targeted towards low level optimization and interpreter code generation. The dialect operations encapsulates low-level pattern match and rewrite "primitives", such as navigating the IR (Operation::getOperand), creating new operations (OpBuilder::create), etc. Many of the operations within this dialect also fuse branching control flow with some form of a predicate comparison operation. This type of fusion reduces the amount of work that an interpreter must do when executing.

An example of this representation is shown below:

```mlir
// The following high level PDL pattern:
pdl.pattern : benefit(1) {
  %resultType = pdl.type
  %inputOperand = pdl.input
  %root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
  pdl.rewrite %root {
    pdl.replace %root with (%inputOperand)
  }
}

// May be represented in the interpreter dialect as follows:
module {
  func @matcher(%arg0: !pdl.operation) {
    pdl_interp.check_operation_name of %arg0 is "foo.op" -> ^bb2, ^bb1
  ^bb1:
    pdl_interp.return
  ^bb2:
    pdl_interp.check_operand_count of %arg0 is 1 -> ^bb3, ^bb1
  ^bb3:
    pdl_interp.check_result_count of %arg0 is 1 -> ^bb4, ^bb1
  ^bb4:
    %0 = pdl_interp.get_operand 0 of %arg0
    pdl_interp.is_not_null %0 : !pdl.value -> ^bb5, ^bb1
  ^bb5:
    %1 = pdl_interp.get_result 0 of %arg0
    pdl_interp.is_not_null %1 : !pdl.value -> ^bb6, ^bb1
  ^bb6:
    pdl_interp.record_match @Rewriters::@rewriter(%0, %arg0 : !pdl.value, !pdl.operation) : benefit(1), loc([%arg0]), root("foo.op") -> ^bb1
  }
  module @Rewriters {
    func @rewriter(%arg0: !pdl.value, %arg1: !pdl.operation) {
      pdl_interp.replace %arg1 with(%arg0)
      pdl_interp.return
    }
  }
}
```

Differential Revision: https://reviews.llvm.org/D84579
  • Loading branch information
River707 committed Aug 26, 2020
1 parent 92c527e commit d289a97
Show file tree
Hide file tree
Showing 25 changed files with 1,387 additions and 69 deletions.
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/CMakeLists.txt
Expand Up @@ -6,6 +6,7 @@ add_subdirectory(LLVMIR)
add_subdirectory(OpenACC)
add_subdirectory(OpenMP)
add_subdirectory(PDL)
add_subdirectory(PDLInterp)
add_subdirectory(Quant)
add_subdirectory(SCF)
add_subdirectory(Shape)
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/PDL/IR/PDLBase.td
Expand Up @@ -49,7 +49,7 @@ def PDL_Dialect : Dialect {
%resultType = pdl.type
%inputOperand = pdl.input
%root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
pdl.rewrite(%root) {
pdl.rewrite %root {
pdl.replace %root with (%inputOperand)
}
}
Expand Down
42 changes: 24 additions & 18 deletions mlir/include/mlir/Dialect/PDL/IR/PDLOps.td
Expand Up @@ -51,17 +51,18 @@ def PDL_ApplyConstraintOp
```
}];

let arguments = (ins Variadic<PDL_PositionalValue>:$args,
ArrayAttr:$params,
StrAttr:$name);
let assemblyFormat = "$name $params `(` $args `:` type($args) `)` attr-dict";
let arguments = (ins StrAttr:$name,
Variadic<PDL_PositionalValue>:$args,
OptionalAttr<ArrayAttr>:$constParams);
let assemblyFormat = [{
$name ($constParams^)? `(` $args `:` type($args) `)` attr-dict
}];

let builders = [
OpBuilder<"OpBuilder &builder, OperationState &state, "
"ValueRange args, ArrayRef<Attribute> params, "
"StringRef name", [{
build(builder, state, args, builder.getArrayAttr(params),
builder.getStringAttr(name));
OpBuilder<"OpBuilder &builder, OperationState &state, StringRef name, "
"ValueRange args = {}, ArrayRef<Attribute> params = {}", [{
build(builder, state, builder.getStringAttr(name), args,
params.empty() ? ArrayAttr() : builder.getArrayAttr(params));
}]>,
];
}
Expand Down Expand Up @@ -135,12 +136,13 @@ def PDL_CreateNativeOp
```
}];

let arguments = (ins StrAttr:$name, Variadic<PDL_PositionalValue>:$arguments,
ArrayAttr:$constantParams);
let arguments = (ins StrAttr:$name,
Variadic<PDL_PositionalValue>:$args,
OptionalAttr<ArrayAttr>:$constParams);
let results = (outs PDL_PositionalValue:$result);
let assemblyFormat = [{
$name $constantParams (`(` $arguments^ `:` type($arguments) `)`)?
`:` type($result) attr-dict
$name ($constParams^)? (`(` $args^ `:` type($args) `)`)? `:` type($result)
attr-dict
}];
let verifier = ?;
}
Expand Down Expand Up @@ -222,7 +224,7 @@ def PDL_OperationOp
`pdl.operation`s are composed of a name, and a set of attribute, operand,
and result type values, that map to what those that would be on a
constructed instance of that operation. The results of a `pdl.operation` are
a handle to the operation itself, and a handle to each of the operation
a handle to the operation itself, and a handle to each of the operation
result values.

When used within a matching context, the name of the operation may be
Expand Down Expand Up @@ -380,24 +382,28 @@ def PDL_RewriteOp : PDL_Op<"rewrite", [
rewrite is specified either via a string name (`name`) to an external
rewrite function, or via the region body. The rewrite region, if specified,
must contain a single block and terminate via the `pdl.rewrite_end`
operation.
operation. If the rewrite is external, it also takes a set of constant
parameters and a set of additional positional values defined within the
matcher as arguments.

Example:

```mlir
// Specify an external rewrite function:
pdl.rewrite "myExternalRewriter"(%root)
pdl.rewrite %root with "myExternalRewriter"(%value : !pdl.value)

// Specify the rewrite inline using PDL:
pdl.rewrite(%root) {
pdl.rewrite %root {
%op = pdl.operation "foo.op"(%arg0, %arg1)
pdl.replace %root with %op
}
```
}];

let arguments = (ins PDL_Operation:$root,
OptionalAttr<StrAttr>:$name);
OptionalAttr<StrAttr>:$name,
Variadic<PDL_PositionalValue>:$externalArgs,
OptionalAttr<ArrayAttr>:$externalConstParams);
let regions = (region AnyRegion:$body);
}

Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/PDLInterp/CMakeLists.txt
@@ -0,0 +1 @@
add_subdirectory(IR)
2 changes: 2 additions & 0 deletions mlir/include/mlir/Dialect/PDLInterp/IR/CMakeLists.txt
@@ -0,0 +1,2 @@
add_mlir_dialect(PDLInterpOps pdl_interp)
add_mlir_doc(PDLInterpOps -gen-op-doc PDLInterpOps Dialects/)
39 changes: 39 additions & 0 deletions mlir/include/mlir/Dialect/PDLInterp/IR/PDLInterp.h
@@ -0,0 +1,39 @@
//===- PDLInterp.h - PDL Interpreter dialect --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the interpreter dialect for the PDL pattern descriptor
// language.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_
#define MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_

#include "mlir/Dialect/PDL/IR/PDL.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

namespace mlir {
namespace pdl_interp {
//===----------------------------------------------------------------------===//
// PDLInterp Dialect
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/PDLInterp/IR/PDLInterpOpsDialect.h.inc"

//===----------------------------------------------------------------------===//
// PDLInterp Dialect Operations
//===----------------------------------------------------------------------===//

#define GET_OP_CLASSES
#include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.h.inc"

} // end namespace pdl_interp
} // end namespace mlir

#endif // MLIR_DIALECT_PDLINTERP_IR_PDLINTERP_H_

0 comments on commit d289a97

Please sign in to comment.