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 
15 #include "mlir/TableGen/GenInfo.h"
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 
24 using namespace mlir;
25 using namespace llvm;
26 
28 
30 
31 // Returns if there is a use of `deprecatedInit` in `field`.
32 static 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`.
85 static 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 
92 static 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.
124 static const mlir::GenInfo *generator;
125 
126 // TableGenMain requires a function pointer so this function is passed in which
127 // simply wraps the call to the generator.
128 static 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 
139 int 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
bool invoke(const llvm::RecordKeeper &records, raw_ostream &os) const
Invokes the generator and returns whether the generator failed.
Definition: GenInfo.h:37
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.