-
Notifications
You must be signed in to change notification settings - Fork 10.8k
/
MlirTblgenMain.cpp
135 lines (115 loc) · 4.51 KB
/
MlirTblgenMain.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//===- MlirTblgenMain.cpp - MLIR Tablegen Driver main -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Main entry function for mlir-tblgen for when built as standalone binary.
//
//===----------------------------------------------------------------------===//
#include "mlir/Tools/mlir-tblgen/MlirTblgenMain.h"
#include "mlir/TableGen/GenInfo.h"
#include "mlir/TableGen/GenNameParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Signals.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
using namespace mlir;
using namespace llvm;
enum DeprecatedAction { None, Warn, Error };
static DeprecatedAction actionOnDeprecatedValue;
// Returns if there is a use of `init` in `record`.
static bool findUse(Record &record, Init *init,
llvm::DenseMap<Record *, bool> &known) {
auto it = known.find(&record);
if (it != known.end())
return it->second;
auto memoize = [&](bool val) {
known[&record] = val;
return val;
};
for (const RecordVal &val : record.getValues()) {
Init *valInit = val.getValue();
if (valInit == init)
return true;
if (auto *di = dyn_cast<DefInit>(valInit)) {
if (findUse(*di->getDef(), init, known))
return memoize(true);
} else if (auto *di = dyn_cast<DagInit>(valInit)) {
for (Init *arg : di->getArgs())
if (auto *di = dyn_cast<DefInit>(arg))
if (findUse(*di->getDef(), init, known))
return memoize(true);
} else if (ListInit *li = dyn_cast<ListInit>(valInit)) {
for (Init *jt : li->getValues())
if (jt == init)
return memoize(true);
}
}
return memoize(false);
}
static void warnOfDeprecatedUses(RecordKeeper &records) {
// This performs a direct check for any def marked as deprecated and then
// finds all uses of deprecated def. Deprecated defs are not expected to be
// either numerous or long lived.
bool deprecatedDefsFounds = false;
for (auto &it : records.getDefs()) {
const RecordVal *r = it.second->getValue("odsDeprecated");
if (!r || !r->getValue())
continue;
llvm::DenseMap<Record *, bool> hasUse;
if (auto *si = dyn_cast<StringInit>(r->getValue())) {
for (auto &jt : records.getDefs()) {
// Skip anonymous defs.
if (jt.second->isAnonymous())
continue;
// Skip all outside main file to avoid flagging redundantly.
unsigned buf =
SrcMgr.FindBufferContainingLoc(jt.second->getLoc().front());
if (buf != SrcMgr.getMainFileID())
continue;
if (findUse(*jt.second, it.second->getDefInit(), hasUse)) {
PrintWarning(jt.second->getLoc(),
"Using deprecated def `" + it.first + "`");
PrintNote(si->getAsUnquotedString());
deprecatedDefsFounds = true;
}
}
}
}
if (deprecatedDefsFounds &&
actionOnDeprecatedValue == DeprecatedAction::Error)
PrintFatalNote("Error'ing out due to deprecated defs");
}
// Generator to invoke.
static const mlir::GenInfo *generator;
// TableGenMain requires a function pointer so this function is passed in which
// simply wraps the call to the generator.
static bool mlirTableGenMain(raw_ostream &os, RecordKeeper &records) {
if (actionOnDeprecatedValue != DeprecatedAction::None)
warnOfDeprecatedUses(records);
if (!generator) {
os << records;
return false;
}
return generator->invoke(records, os);
}
int mlir::MlirTblgenMain(int argc, char **argv) {
llvm::InitLLVM y(argc, argv);
llvm::cl::opt<DeprecatedAction, true> actionOnDeprecated(
"on-deprecated", llvm::cl::desc("Action to perform on deprecated def"),
llvm::cl::values(
clEnumValN(DeprecatedAction::None, "none", "No action"),
clEnumValN(DeprecatedAction::Warn, "warn", "Warn on use"),
clEnumValN(DeprecatedAction::Error, "error", "Error on use")),
cl::location(actionOnDeprecatedValue), llvm::cl::init(Warn));
llvm::cl::opt<const mlir::GenInfo *, true, mlir::GenNameParser> generator(
"", llvm::cl::desc("Generator to run"), cl::location(::generator));
cl::ParseCommandLineOptions(argc, argv);
return TableGenMain(argv[0], &mlirTableGenMain);
}