MLIR 22.0.0git
MlirTblgenMain.cpp
Go to the documentation of this file.
1//===- MlirTblgenMain.cpp - MLIR Tablegen Driver main -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Main entry function for mlir-tblgen for when built as standalone binary.
10//
11//===----------------------------------------------------------------------===//
12
14
17#include "llvm/Support/CommandLine.h"
18#include "llvm/Support/InitLLVM.h"
19#include "llvm/Support/Signals.h"
20#include "llvm/TableGen/Error.h"
21#include "llvm/TableGen/Main.h"
22#include "llvm/TableGen/Record.h"
23
24using namespace mlir;
25using namespace llvm;
26
28
30
31// Returns if there is a use of `deprecatedInit` in `field`.
32static bool findUse(const Init *field, const Init *deprecatedInit,
34 if (field == deprecatedInit)
35 return true;
36
37 auto it = known.find(field);
38 if (it != known.end())
39 return it->second;
40
41 auto memoize = [&](bool val) {
42 known[field] = val;
43 return val;
44 };
45
46 if (auto *defInit = dyn_cast<DefInit>(field)) {
47 // Only recurse into defs if they are anonymous.
48 // Non-anonymous defs are handled by the main loop, with a proper
49 // deprecation warning for each. Returning true here, would cause
50 // all users of a def to also emit a deprecation warning.
51 if (!defInit->getDef()->isAnonymous())
52 // Purposefully not memoize as to not include every def use in the map.
53 // This is also a trivial case we return false for in constant time.
54 return false;
55
56 return memoize(
57 llvm::any_of(defInit->getDef()->getValues(), [&](const RecordVal &val) {
58 return findUse(val.getValue(), deprecatedInit, known);
59 }));
60 }
61
62 if (auto *dagInit = dyn_cast<DagInit>(field)) {
63 if (findUse(dagInit->getOperator(), deprecatedInit, known))
64 return memoize(true);
65
66 return memoize(llvm::any_of(dagInit->getArgs(), [&](const Init *arg) {
67 return findUse(arg, deprecatedInit, known);
68 }));
69 }
70
71 if (const ListInit *li = dyn_cast<ListInit>(field)) {
72 return memoize(llvm::any_of(li->getElements(), [&](const Init *jt) {
73 return findUse(jt, deprecatedInit, known);
74 }));
75 }
76
77 // Purposefully don't use memoize here. There is no need to cache the result
78 // for every kind of init (e.g. BitInit or StringInit), which will always
79 // return false. Doing so would grow the DenseMap to include almost every Init
80 // within the main file.
81 return false;
82}
83
84// Returns if there is a use of `deprecatedInit` in `record`.
85static bool findUse(Record &record, const Init *deprecatedInit,
87 return llvm::any_of(record.getValues(), [&](const RecordVal &val) {
88 return findUse(val.getValue(), deprecatedInit, known);
89 });
90}
91
92static void warnOfDeprecatedUses(const RecordKeeper &records) {
93 // This performs a direct check for any def marked as deprecated and then
94 // finds all uses of deprecated def. Deprecated defs are not expected to be
95 // either numerous or long lived.
96 bool deprecatedDefsFounds = false;
97 for (auto &it : records.getDefs()) {
98 const RecordVal *r = it.second->getValue("odsDeprecated");
99 if (!r || !r->getValue())
100 continue;
101
103 if (auto *si = dyn_cast<StringInit>(r->getValue())) {
104 for (auto &jt : records.getDefs()) {
105 // Skip anonymous defs.
106 if (jt.second->isAnonymous())
107 continue;
108
109 if (findUse(*jt.second, it.second->getDefInit(), hasUse)) {
110 PrintWarning(jt.second->getLoc(),
111 "Using deprecated def `" + it.first + "`");
112 PrintNote(si->getAsUnquotedString());
113 deprecatedDefsFounds = true;
114 }
115 }
116 }
117 }
118 if (deprecatedDefsFounds &&
120 PrintFatalNote("Error'ing out due to deprecated defs");
121}
122
123// Generator to invoke.
125
126// TableGenMain requires a function pointer so this function is passed in which
127// simply wraps the call to the generator.
128static bool mlirTableGenMain(raw_ostream &os, const RecordKeeper &records) {
130 warnOfDeprecatedUses(records);
131
132 if (!generator) {
133 os << records;
134 return false;
135 }
136 return generator->invoke(records, os);
137}
138
139int mlir::MlirTblgenMain(int argc, char **argv) {
140
141 llvm::InitLLVM y(argc, argv);
142
143 llvm::cl::opt<DeprecatedAction, true> actionOnDeprecated(
144 "on-deprecated", llvm::cl::desc("Action to perform on deprecated def"),
145 llvm::cl::values(
146 clEnumValN(DeprecatedAction::None, "none", "No action"),
147 clEnumValN(DeprecatedAction::Warn, "warn", "Warn on use"),
148 clEnumValN(DeprecatedAction::Error, "error", "Error on use")),
149 cl::location(actionOnDeprecatedValue), llvm::cl::init(Warn));
150
151 llvm::cl::opt<const mlir::GenInfo *, true, mlir::GenNameParser> generator(
152 "", llvm::cl::desc("Generator to run"), cl::location(::generator));
153
154 cl::ParseCommandLineOptions(argc, argv);
155
156 return TableGenMain(argv[0], &mlirTableGenMain);
157}
static DeprecatedAction actionOnDeprecatedValue
static bool findUse(const Init *field, const Init *deprecatedInit, llvm::DenseMap< const Init *, bool > &known)
static const mlir::GenInfo * generator
static void warnOfDeprecatedUses(const RecordKeeper &records)
static bool mlirTableGenMain(raw_ostream &os, const RecordKeeper &records)
DeprecatedAction
@ Error
@ Warn
@ None
Structure to group information about a generator (argument to invoke via mlir-tblgen,...
Definition GenInfo.h:29
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
Include the generated interface declarations.
int MlirTblgenMain(int argc, char **argv)
Main Program for tools like 'mlir-tblgen' with custom backends.