[llvm-branch-commits] [mlir] 14f2415 - [mlir][LLVMIR] Add 'llvm.switch' op

2020-12-17 Thread Brian Gesiak via llvm-branch-commits

Author: Brian Gesiak
Date: 2020-12-17T14:11:21-05:00
New Revision: 14f24155a5915a295bd965bb6062bfeab217b9c8

URL: 
https://github.com/llvm/llvm-project/commit/14f24155a5915a295bd965bb6062bfeab217b9c8
DIFF: 
https://github.com/llvm/llvm-project/commit/14f24155a5915a295bd965bb6062bfeab217b9c8.diff

LOG: [mlir][LLVMIR] Add 'llvm.switch' op

The LLVM IR 'switch' instruction allows control flow to be transferred
to one of any number of branches depending on an integer control value,
or a default value if the control does not match any branch values. This patch
adds `llvm.switch` to the MLIR LLVMIR dialect, as well as translation routines
for lowering it to LLVM IR.

To store a variable number of operands for a variable number of branch
destinations, the new op makes use of the `AttrSizedOperandSegments`
trait. It stores its default branch operands as one segment, and all
remaining case branches' operands as another. It also stores pairs of
begin and end offset values to delineate the sub-range of each case branch's
operands. There's probably a better way to implement this, since the
offset computation complicates several parts of the op definition. This is the
approach I settled on because in doing so I was able to delegate to the default
op builder member functions. However, it may be preferable to instead specify
`skipDefaultBuilders` in the op's ODS, or use a completely separate
approach; feedback is welcome!

Another contentious part of this patch may be the custom printer and
parser functions for the op. Ideally I would have liked the MLIR to be
printed in this way:

```
llvm.switch %0, ^bb1(%1 : !llvm.i32) [
  1: ^bb2,
  2: ^bb3(%2, %3 : !llvm.i32, !llvm.i32)
]
```

The above would resemble how LLVM IR is formatted for the 'switch'
instruction. But I found it difficult to print and parse something like
this, whether I used the declarative assembly format or custom functions.
I also was not sure a multi-line format would be welcome -- it seems
like most MLIR ops do not use newlines. Again, I'd be happy to hear any
feedback here as well, or on any other aspect of the patch.

Differential Revision: https://reviews.llvm.org/D93005

Added: 


Modified: 
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Dialect/LLVMIR/invalid.mlir
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/llvmir.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 0088fe38246b..9608e15bb81a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -635,6 +635,50 @@ def LLVM_UnreachableOp : LLVM_TerminatorOp<"unreachable", 
[]> {
   let printer = [{ p << getOperationName(); }];
 }
 
+def LLVM_SwitchOp : LLVM_TerminatorOp<"switch",
+[AttrSizedOperandSegments, DeclareOpInterfaceMethods,
+ NoSideEffect]> {
+  let arguments = (ins LLVM_i32:$value,
+   Variadic:$defaultOperands,
+   Variadic:$caseOperands,
+   OptionalAttr:$case_values,
+   OptionalAttr:$case_operand_offsets,
+   OptionalAttr:$branch_weights);
+  let successors = (successor
+AnySuccessor:$defaultDestination,
+VariadicSuccessor:$caseDestinations);
+
+  let verifier = [{ return ::verify(*this); }];
+  let assemblyFormat = [{
+$value `,`
+$defaultDestination (`(` $defaultOperands^ `:` type($defaultOperands) `)`)?
+`[` `\n` custom($case_values, $caseDestinations,
+   $caseOperands, type($caseOperands),
+   $case_operand_offsets) `]`
+attr-dict
+  }];
+
+  let builders = [
+OpBuilderDAG<(ins "Value":$value,
+  "Block *":$defaultDestination,
+  "ValueRange":$defaultOperands,
+  CArg<"ArrayRef", "{}">:$caseValues,
+  CArg<"BlockRange", "{}">:$caseDestinations,
+  CArg<"ArrayRef", "{}">:$caseOperands,
+  CArg<"ArrayRef", "{}">:$branchWeights)>,
+LLVM_TerminatorPassthroughOpBuilder
+  ];
+
+  let extraClassDeclaration = [{
+/// Return the operands for the case destination block at the given index.
+OperandRange getCaseOperands(unsigned index);
+
+/// Return a mutable range of operands for the case destination block at 
the
+/// given index.
+MutableOperandRange getCaseOperandsMutable(unsigned index);
+  }];
+}
+
 

 // Auxiliary operations (do not appear in LLVM IR but necessary for the dialect
 // to work correctly).

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp 
b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index d70a327824b7..9b2c88c30a86 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/ml

[llvm-branch-commits] [mlir] 09b0e08 - [mlir] Print bad size in AttrSizedOperandSegments

2020-12-12 Thread Brian Gesiak via llvm-branch-commits

Author: Brian Gesiak
Date: 2020-12-12T13:12:31-05:00
New Revision: 09b0e0884a3ea561f11a97644a9cf6c15eac6ec0

URL: 
https://github.com/llvm/llvm-project/commit/09b0e0884a3ea561f11a97644a9cf6c15eac6ec0
DIFF: 
https://github.com/llvm/llvm-project/commit/09b0e0884a3ea561f11a97644a9cf6c15eac6ec0.diff

LOG: [mlir] Print bad size in AttrSizedOperandSegments

When printing verification errors for ops with the incorrect number of
operand segments, print the required number as well as the actual
number. Split off from D93005.

Differential Revision: https://reviews.llvm.org/D93145

Added: 


Modified: 
mlir/test/IR/traits.mlir
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp

Removed: 




diff  --git a/mlir/test/IR/traits.mlir b/mlir/test/IR/traits.mlir
index c023db338a73..e3604b7b5387 100644
--- a/mlir/test/IR/traits.mlir
+++ b/mlir/test/IR/traits.mlir
@@ -448,7 +448,7 @@ func @failedResultSizeAttrWrongTotalSize() {
 // -
 
 func @failedResultSizeAttrWrongCount() {
-  // expected-error @+1 {{'result_segment_sizes' attribute for specifying 
result segments must have 4 elements}}
+  // expected-error @+1 {{'result_segment_sizes' attribute for specifying 
result segments must have 4 elements, but got 3}}
   %0:4 = "test.attr_sized_results"() {result_segment_sizes = dense<[2, 1, 1]>: 
vector<3xi32>} : () -> (i32, i32, i32, i32)
 }
 

diff  --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp 
b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index 04bc10d338d7..c97aa043bb6c 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -2211,7 +2211,7 @@ void OpOperandAdaptorEmitter::addVerification() {
 auto numElements = 
sizeAttr.getType().cast<::mlir::ShapedType>().getNumElements();
 if (numElements != {1})
   return emitError(loc, "'{0}' attribute for specifying {2} segments "
-   "must have {1} elements");
+   "must have {1} elements, but got ") << numElements;
   }
   )";
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits