15#define FAILURE_IF_FAILED(RES) \
26#define FAILURE_IF_NULLOPT_OR_FAILED(RES) \
27 if (didntSucceed(RES)) { \
32#define ERROR_IF(COND, MSG) \
34 return parser.emitError(loc, MSG); \
51 ERROR_IF(!isOptional,
"expected bare identifier")
55 if (
const auto res = env.
lookupOrCreate(creationPolicy, name, loc, vk)) {
57 didCreate = res->second;
61 switch (creationPolicy) {
63 return parser.
emitError(loc,
"use of undeclared identifier '" + name +
"'");
65 llvm_unreachable(
"got nullopt for Policy::May");
67 return parser.
emitError(loc,
"redefinition of identifier '" + name +
"'");
69 llvm_unreachable(
"unknown Policy");
72FailureOr<VarInfo::ID> DimLvlMapParser::parseVarUsage(
VarKind vk,
76 const bool isOptional =
false;
78 const auto res = parseVar(vk, isOptional, creationPolicy,
id, didCreate);
80 assert(requireKnown ? !didCreate :
true);
84FailureOr<VarInfo::ID> DimLvlMapParser::parseVarBinding(
VarKind vk,
86 const auto loc = parser.getCurrentLocation();
89 const bool isOptional =
false;
91 const auto res = parseVar(vk, isOptional, creationPolicy,
id, didCreate);
93 assert(requireKnown ? !didCreate : didCreate);
98FailureOr<std::pair<Var, bool>>
99DimLvlMapParser::parseOptionalVarBinding(
VarKind vk,
bool requireKnown) {
100 const auto loc = parser.getCurrentLocation();
103 const bool isOptional =
true;
105 const auto res = parseVar(vk, isOptional, creationPolicy,
id, didCreate);
106 if (res.has_value()) {
109 return std::make_pair(bindVar(loc,
id),
true);
112 return std::make_pair(env.bindUnusedVar(vk),
false);
116 MLIRContext *context = parser.getContext();
117 const auto var = env.bindVar(
id);
118 const auto &info = std::as_const(env).access(
id);
119 const auto name = info.getName();
120 const auto num = *info.
getNum();
121 switch (info.getKind()) {
124 dimsAndSymbols.emplace_back(name, affine);
125 lvlsAndSymbols.emplace_back(name, affine);
135 llvm_unreachable(
"unknown VarKind");
151 return DimLvlMap(env.getRanks().getSymRank(), dimSpecs, lvlSpecs);
154ParseResult DimLvlMapParser::parseSymbolBindingList() {
158 " in symbol binding list");
161ParseResult DimLvlMapParser::parseLvlVarBindingList() {
164 [
this]() {
return ParseResult(parseVarBinding(
VarKind::Level)); },
165 " in level declaration list");
172ParseResult DimLvlMapParser::parseDimSpecList() {
173 return parser.parseCommaSeparatedList(
175 [
this]() -> ParseResult {
return parseDimSpec(); },
176 " in dimension-specifier list");
179ParseResult DimLvlMapParser::parseDimSpec() {
183 const DimVar var = env.getVar(*varID).cast<DimVar>();
187 if (succeeded(parser.parseOptionalEqual())) {
191 DimExpr expr{affine};
194 SparseTensorDimSliceAttr slice;
195 if (succeeded(parser.parseOptionalColon())) {
196 const auto loc = parser.getCurrentLocation();
199 slice = llvm::dyn_cast<SparseTensorDimSliceAttr>(attr);
200 ERROR_IF(!slice,
"expected SparseTensorDimSliceAttr")
203 dimSpecs.emplace_back(var, expr, slice);
211ParseResult DimLvlMapParser::parseLvlSpecList() {
228 const auto declaredLvlRank = env.getRanks().getLvlRank();
229 const bool requireLvlVarBinding = declaredLvlRank != 0;
231 const auto loc = parser.getCurrentLocation();
232 const auto res = parser.parseCommaSeparatedList(
234 [
this, requireLvlVarBinding]() -> ParseResult {
235 return parseLvlSpec(requireLvlVarBinding);
237 " in level-specifier list");
239 const auto specLvlRank = lvlSpecs.size();
240 ERROR_IF(requireLvlVarBinding && specLvlRank != declaredLvlRank,
241 "Level-rank mismatch between forward-declarations and specifiers. "
243 Twine(declaredLvlRank) +
" level-variables; but got " +
244 Twine(specLvlRank) +
" level-specifiers.")
255 return Twine(n) +
"th";
260DimLvlMapParser::parseLvlVarBinding(
bool requireLvlVarBinding) {
262 if (!requireLvlVarBinding)
265 const auto loc = parser.getCurrentLocation();
274 const auto &info = std::as_const(env).access(*varID);
275 const auto var = info.getVar().
cast<LvlVar>();
276 const auto forwardNum = var.
getNum();
277 const auto specNum = lvlSpecs.size();
279 "Level-variable ordering mismatch. The variable '" + info.getName() +
280 "' was forward-declared as the " +
nth(forwardNum) +
281 " level; but is bound by the " +
nth(specNum) +
290 const auto varRes = parseLvlVarBinding(requireLvlVarBinding);
292 const LvlVar var = *varRes;
297 LvlExpr expr{affine};
300 const auto type = lvlTypeParser.parseLvlType(parser);
303 lvlSpecs.emplace_back(var, expr, static_cast<LevelType>(*type));
static bool didntSucceed(OptionalParseResult res)
Helper function for FAILURE_IF_NULLOPT_OR_FAILED to avoid duplicating its RES parameter.
#define FAILURE_IF_FAILED(RES)
#define ERROR_IF(COND, MSG)
static Twine nth(Var::Num n)
#define FAILURE_IF_NULLOPT_OR_FAILED(RES)
@ Paren
Parens surrounding zero or more operands.
@ OptionalBraces
{} brackets surrounding zero or more operands, or nothing.
@ OptionalSquare
Square brackets supporting zero or more ops, or nothing.
virtual ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())=0
Parse a list of comma-separated items with an optional delimiter.
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
This class represents a diagnostic that is inflight and set to be reported.
This class implements Optional functionality for ParseResult.
bool has_value() const
Returns true if we contain a valid ParseResult value.
FailureOr< DimLvlMap > parseDimLvlMap()
DimLvlMapParser(AsmParser &parser)
std::optional< std::pair< VarInfo::ID, bool > > lookupOrCreate(Policy creationPolicy, StringRef name, llvm::SMLoc loc, VarKind vk)
Looks up or creates a variable according to the given Policy.
ID
Newtype for unique identifiers of VarInfo records, to ensure they aren't confused with Var::Num.
A concrete variable, to be used in our variant of AffineExpr.
constexpr Num getNum() const
VarKind
The three kinds of variables that Var can be.
Include the generated interface declarations.
AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context)
These free functions allow clients of the API to not use classes in detail.
AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context)