Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error if duplicated mnemonics are found. #88

Merged
merged 1 commit into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/llvm-dialects/TableGen/Dialects.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"

namespace llvm {
class DagInit;
Expand All @@ -47,10 +48,11 @@ class GenDialect {
std::string cppNamespace;
std::vector<DialectType *> types;
std::vector<OpClass *> opClasses;
llvm::StringMap<unsigned> operationCounts;
std::vector<std::unique_ptr<Operation>> operations;

public:
void finalize();
void finalize(llvm::raw_ostream &errs);

llvm::ArrayRef<std::vector<Trait *>> attribute_lists() const {
return m_attributeLists;
Expand Down
16 changes: 14 additions & 2 deletions lib/TableGen/Dialects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
using namespace llvm;
using namespace llvm_dialects;

void GenDialect::finalize() {
void GenDialect::finalize(raw_ostream &errs) {
// Build the list of different attribute lists.
auto traitLess = [](Trait *lhs, Trait *rhs) {
return lhs->getName() < rhs->getName();
Expand All @@ -41,6 +41,18 @@ void GenDialect::finalize() {

std::vector<Operation *> traitOperations;

bool hasDuplicates = false;
for (const auto &[op, count] : operationCounts) {
if (count != 1) {
errs << "Found op with non-unique mnemonic: " << op << '\n';
hasDuplicates = true;
}
}

if (hasDuplicates)
report_fatal_error(
"Aborting dialect generation since non-unique mnemonics were found!");

for (const auto &op : operations) {
if (op->traits.empty())
continue;
Expand Down Expand Up @@ -219,5 +231,5 @@ void GenDialectsContext::init(RecordKeeper &records,
}

for (auto &dialectEntry : m_dialects)
dialectEntry.second->finalize();
dialectEntry.second->finalize(llvm::errs());
}
1 change: 1 addition & 0 deletions lib/TableGen/Operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ bool Operation::parse(raw_ostream &errs, GenDialectsContext *context,

op->m_builders.push_back(std::move(builder));

++dialect->operationCounts[op->mnemonic];
Flakebi marked this conversation as resolved.
Show resolved Hide resolved
dialect->operations.push_back(std::move(op));

return true;
Expand Down
45 changes: 45 additions & 0 deletions test/tablegen/duplicate-ops.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// RUN: not --crash llvm-dialects-tblgen -gen-dialect-defs -dialect=dups -I%S/../../include %s 2>&1 | FileCheck --check-prefixes=CHECK %s

// CHECK: Found op with non-unique mnemonic: duplicate.op
// CHECK-NEXT: Found op with non-unique mnemonic: duplicate.op.1
// CHECK-NEXT: LLVM ERROR: Aborting dialect generation since non-unique mnemonics were found!

include "llvm-dialects/Dialect/Dialect.td"

def TestDialect : Dialect {
let name = "dups";
let cppNamespace = "dups";
}

class TestOp<string mnemonic_, list<Trait> traits_>
: Op<TestDialect, mnemonic_, traits_>;

def DuplicateOp : TestOp<"duplicate.op",
[]> {
let results = (outs);
let arguments = (ins);
}

def DuplicateOp1 : TestOp<"duplicate.op",
[]> {
let results = (outs);
let arguments = (ins);
}

def DuplicateOp2 : TestOp<"duplicate.op.1",
[]> {
let results = (outs);
let arguments = (ins);
}

def DuplicateOp3 : TestOp<"duplicate.op.1",
[]> {
let results = (outs);
let arguments = (ins);
}

def UniqueOp : TestOp<"unique.op",
[]> {
let results = (outs);
let arguments = (ins);
}
Loading