with Interfaces. Here we will show how to plug dialect specific information
into generic transformations like shape inference and inlining.
- [Chapter #5](Ch-5.md): Partially lowering to lower-level dialects. We'll
- convert some our high level language specific semantics towards a generic
+ convert some of our high level language specific semantics towards a generic
affine oriented dialect for optimization.
- [Chapter #6](Ch-6.md): Lowering to LLVM and code generation. Here we'll
target LLVM IR for code generation, and detail more of the lowering
and seeing it round-trip without tripping the verifier:
```mlir
-// RUN: toyc %s -emit=mlir
-
func @main() {
%0 = "toy.print"() : () -> tensor<2x3xf64>
}
return failure();
// Otherwise, we have a redundant transpose. Use the rewriter.
- rewriter.replaceOp(op, {transposeInputOp.getOperand()}, {transposeInputOp});
+ rewriter.replaceOp(op, {transposeInputOp.getOperand()});
return success();
}
};
}
// Multiply and store into the output buffer.
- affine.for %arg0 = 0 to 2 {
- affine.for %arg1 = 0 to 3 {
+ affine.for %arg0 = 0 to 3 {
+ affine.for %arg1 = 0 to 2 {
%3 = affine.load %1[%arg0, %arg1] : memref<3x2xf64>
%4 = affine.load %1[%arg0, %arg1] : memref<3x2xf64>
%5 = mulf %3, %4 : f64
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// The generic call operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// The generic call operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// The generic call operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// The generic call operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// The generic call operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
// StructType.
let results = (outs Toy_Type);
- // The return operation only emits the input in the format if it is present.
+ // Specialize assembly printing and parsing using a declarative format.
let assemblyFormat = [{
$callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
}];
resultType.isa<mlir::UnrankedTensorType>())
return mlir::success();
- return op.emitError() << "type of return operand ("
- << *op.operand_type_begin()
+ return op.emitError() << "type of return operand (" << inputType
<< ") doesn't match function result type ("
- << results.front() << ")";
+ << resultType << ")";
}
//===----------------------------------------------------------------------===//
/// parameters names.
void ASTDumper::dump(PrototypeAST *node) {
INDENT();
- llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "'\n";
+ llvm::errs() << "Proto '" << node->getName() << "' " << loc(node) << "\n";
indent();
llvm::errs() << "Params: [";
llvm::interleaveComma(node->getArgs(), llvm::errs(),
namespace mlir {
-/// Initialize LLVM passes that can be when running MLIR code using
+/// Initialize LLVM passes that can be used when running MLIR code using
/// ExecutionEngine.
void initializeLLVMPasses();
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK: Module:
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}ast.toy:4:1
# CHECK-NEXT: Params: [a, b]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: } // Block
# CHECK-NEXT: Function
-# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}ast.toy:8:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl a<> @{{.*}}ast.toy:11:3
# CHECK-NEXT: VarDecl b<> @{{.*}}struct-ast.toy:5:3
# CHECK-NEXT: ]
# CHECK-NEXT:Function
-# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}struct-ast.toy:9:1'
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}struct-ast.toy:9:1
# CHECK-NEXT: Params: [value]
# CHECK-NEXT: Block {
# CHECK-NEXT: Return
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT:Function
-# CHECK-NEXT: Proto 'main' @{{.*}}struct-ast.toy:14:1'
+# CHECK-NEXT: Proto 'main' @{{.*}}struct-ast.toy:14:1
# CHECK-NEXT: Params: []
# CHECK-NEXT: Block {
# CHECK-NEXT: VarDecl value<Struct> @{{.*}}struct-ast.toy:16:3