Unique trait list during ODS Operator trait construction

Concatting lists in TableGen is easy, creating unique lists less so. There is no reason for duplicated op traits so we could throw an error instead but duplicates could occur due to concatting different list of traits in ODS (e.g., for convenience reasons), so just dedup them during Operator trait construction instead.

PiperOrigin-RevId: 286488423
This commit is contained in:
Jacques Pienaar 2019-12-19 16:43:35 -08:00 committed by A. Unique TensorFlower
parent 8020ad3e39
commit b6d54a1ba3
3 changed files with 17 additions and 7 deletions

View File

@ -1586,6 +1586,7 @@ class Op<Dialect dialect, string mnemonic, list<OpTrait> props = []> {
bit hasFolder = 0; bit hasFolder = 0;
// Op traits. // Op traits.
// Note: The list of traits will be uniqued by ODS.
list<OpTrait> traits = props; list<OpTrait> traits = props;
// Additional code that will be added to the public part of the generated // Additional code that will be added to the public part of the generated

View File

@ -23,6 +23,7 @@
#include "mlir/TableGen/OpTrait.h" #include "mlir/TableGen/OpTrait.h"
#include "mlir/TableGen/Predicate.h" #include "mlir/TableGen/Predicate.h"
#include "mlir/TableGen/Type.h" #include "mlir/TableGen/Type.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h" #include "llvm/TableGen/Record.h"
@ -293,12 +294,18 @@ void tblgen::Operator::populateOpStructure() {
results.push_back({name, TypeConstraint(resultDef)}); results.push_back({name, TypeConstraint(resultDef)});
} }
auto traitListInit = def.getValueAsListInit("traits"); // Create list of traits, skipping over duplicates: appending to lists in
if (!traitListInit) // tablegen is easy, making them unique less so, so dedupe here.
return; if (auto traitList = def.getValueAsListInit("traits")) {
traits.reserve(traitListInit->size()); // This is uniquing based on pointers of the trait.
for (auto traitInit : *traitListInit) SmallPtrSet<const llvm::Init *, 32> traitSet;
traits.push_back(OpTrait::create(traitInit)); traits.reserve(traitSet.size());
for (auto traitInit : *traitList) {
// Keep traits in the same order while skipping over duplicates.
if (traitSet.insert(traitInit).second)
traits.push_back(OpTrait::create(traitInit));
}
}
// Handle regions // Handle regions
auto *regionsDag = def.getValueAsDag("regions"); auto *regionsDag = def.getValueAsDag("regions");

View File

@ -9,7 +9,9 @@ def Test_Dialect : Dialect {
class NS_Op<string mnemonic, list<OpTrait> traits> : class NS_Op<string mnemonic, list<OpTrait> traits> :
Op<Test_Dialect, mnemonic, traits>; Op<Test_Dialect, mnemonic, traits>;
def NS_AOp : NS_Op<"a_op", [NoSideEffect]> { // NoSideEffect trait is included twice to ensure it gets uniqued during
// emission.
def NS_AOp : NS_Op<"a_op", [NoSideEffect, NoSideEffect]> {
let arguments = (ins let arguments = (ins
I32:$a, I32:$a,
Variadic<F32>:$b, Variadic<F32>:$b,