Expand Up
@@ -1119,17 +1119,43 @@ void OperationFormat::genElementParser(FormatElement *element, MethodBody &body,
GenContext genCtx) {
// / Optional Group.
if (auto *optional = dyn_cast<OptionalElement>(element)) {
ArrayRef<FormatElement *> elements =
optional->getThenElements ().drop_front (optional->getParseStart ());
auto genElementParsers = [&](FormatElement *firstElement,
ArrayRef<FormatElement *> elements,
bool thenGroup) {
// If the anchor is a unit attribute, we don't need to print it. When
// parsing, we will add this attribute if this group is present.
FormatElement *elidedAnchorElement = nullptr ;
auto *anchorAttr = dyn_cast<AttributeVariable>(optional->getAnchor ());
if (anchorAttr && anchorAttr != firstElement &&
anchorAttr->isUnitAttr ()) {
elidedAnchorElement = anchorAttr;
if (!thenGroup == optional->isInverted ()) {
// Add the anchor unit attribute to the operation state.
body << " result.addAttribute(\" " << anchorAttr->getVar ()->name
<< " \" , parser.getBuilder().getUnitAttr());\n " ;
}
}
// Generate the rest of the elements inside an optional group. Elements in
// an optional group after the guard are parsed as required.
for (FormatElement *childElement : elements)
if (childElement != elidedAnchorElement)
genElementParser (childElement, body, attrTypeCtx,
GenContext::Optional);
};
ArrayRef<FormatElement *> thenElements =
optional->getThenElements (/* parseable=*/ true );
// Generate a special optional parser for the first element to gate the
// parsing of the rest of the elements.
FormatElement *firstElement = elements .front ();
FormatElement *firstElement = thenElements .front ();
if (auto *attrVar = dyn_cast<AttributeVariable>(firstElement)) {
genElementParser (attrVar, body, attrTypeCtx);
body << " if (" << attrVar->getVar ()->name << " Attr) {\n " ;
} else if (auto *literal = dyn_cast<LiteralElement>(firstElement)) {
body << " if (succeeded(parser.parseOptional" ;
body << " if (::mlir:: succeeded(parser.parseOptional" ;
genLiteralParser (literal->getSpelling (), body);
body << " )) {\n " ;
} else if (auto *opVar = dyn_cast<OperandVariable>(firstElement)) {
Expand All
@@ -1151,31 +1177,18 @@ void OperationFormat::genElementParser(FormatElement *element, MethodBody &body,
}
}
// If the anchor is a unit attribute, we don't need to print it. When
// parsing, we will add this attribute if this group is present.
FormatElement *elidedAnchorElement = nullptr ;
auto *anchorAttr = dyn_cast<AttributeVariable>(optional->getAnchor ());
if (anchorAttr && anchorAttr != firstElement && anchorAttr->isUnitAttr ()) {
elidedAnchorElement = anchorAttr;
// Add the anchor unit attribute to the operation state.
body << " result.addAttribute(\" " << anchorAttr->getVar ()->name
<< " \" , parser.getBuilder().getUnitAttr());\n " ;
}
// Generate the rest of the elements inside an optional group. Elements in
// an optional group after the guard are parsed as required.
for (FormatElement *childElement : llvm::drop_begin (elements, 1 ))
if (childElement != elidedAnchorElement)
genElementParser (childElement, body, attrTypeCtx, GenContext::Optional);
genElementParsers (firstElement, thenElements.drop_front (),
/* thenGroup=*/ true );
body << " }" ;
// Generate the else elements.
auto elseElements = optional->getElseElements ();
if (!elseElements.empty ()) {
body << " else {\n " ;
for (FormatElement *childElement : elseElements)
genElementParser (childElement, body, attrTypeCtx);
ArrayRef<FormatElement *> elseElements =
optional->getElseElements (/* parsable=*/ true );
genElementParsers (elseElements.front (), elseElements,
/* thenGroup=*/ false );
body << " }" ;
}
body << " \n " ;
Expand Down
Expand Up
@@ -1842,15 +1855,15 @@ static void genOptionalGroupPrinterAnchor(FormatElement *anchor,
const NamedTypeConstraint *var = element->getVar ();
std::string name = op.getGetterName (var->name );
if (var->isOptional ())
body << " if ( " << name << " ()) { \n " ;
body << name << " ()" ;
else if (var->isVariadic ())
body << " if ( !" << name << " ().empty()) { \n " ;
body << " !" << name << " ().empty()" ;
})
.Case <RegionVariable>([&](RegionVariable *element) {
const NamedRegion *var = element->getVar ();
std::string name = op.getGetterName (var->name );
// TODO: Add a check for optional regions here when ODS supports it.
body << " if ( !" << name << " ().empty()) { \n " ;
body << " !" << name << " ().empty()" ;
})
.Case <TypeDirective>([&](TypeDirective *element) {
genOptionalGroupPrinterAnchor (element->getArg (), op, body);
Expand All
@@ -1859,8 +1872,7 @@ static void genOptionalGroupPrinterAnchor(FormatElement *anchor,
genOptionalGroupPrinterAnchor (element->getInputs (), op, body);
})
.Case <AttributeVariable>([&](AttributeVariable *attr) {
body << " if ((*this)->getAttr(\" " << attr->getVar ()->name
<< " \" )) {\n " ;
body << " (*this)->getAttr(\" " << attr->getVar ()->name << " \" )" ;
});
}
Expand Down
Expand Up
@@ -1912,39 +1924,45 @@ void OperationFormat::genElementPrinter(FormatElement *element,
if (OptionalElement *optional = dyn_cast<OptionalElement>(element)) {
// Emit the check for the presence of the anchor element.
FormatElement *anchor = optional->getAnchor ();
body << " if (" ;
if (optional->isInverted ())
body << " !" ;
genOptionalGroupPrinterAnchor (anchor, op, body);
body << " ) {\n " ;
body.indent ();
// If the anchor is a unit attribute, we don't need to print it. When
// parsing, we will add this attribute if this group is present.
auto elements = optional->getThenElements ();
ArrayRef<FormatElement *> thenElements = optional->getThenElements ();
ArrayRef<FormatElement *> elseElements = optional->getElseElements ();
FormatElement *elidedAnchorElement = nullptr ;
auto *anchorAttr = dyn_cast<AttributeVariable>(anchor);
if (anchorAttr && anchorAttr != elements.front () &&
if (anchorAttr && anchorAttr != thenElements.front () &&
(elseElements.empty () || anchorAttr != elseElements.front ()) &&
anchorAttr->isUnitAttr ()) {
elidedAnchorElement = anchorAttr;
}
auto genElementPrinters = [&](ArrayRef<FormatElement *> elements) {
for (FormatElement *childElement : elements) {
if (childElement != elidedAnchorElement) {
genElementPrinter (childElement, body, op, shouldEmitSpace,
lastWasPunctuation);
}
}
};
// Emit each of the elements.
for (FormatElement *childElement : elements) {
if (childElement != elidedAnchorElement) {
genElementPrinter (childElement, body, op, shouldEmitSpace,
lastWasPunctuation);
}
}
body << " }" ;
genElementPrinters (thenElements);
body << " }" ;
// Emit each of the else elements.
auto elseElements = optional->getElseElements ();
if (!elseElements.empty ()) {
body << " else {\n " ;
for (FormatElement *childElement : elseElements) {
genElementPrinter (childElement, body, op, shouldEmitSpace,
lastWasPunctuation);
}
body << " }" ;
genElementPrinters (elseElements);
body << " }" ;
}
body << " \n " ;
body. unindent () << " \n " ;
return ;
}
Expand Down
Expand Up
@@ -2170,9 +2188,9 @@ class OpFormatParser : public FormatParser {
verifyCustomDirectiveArguments (SMLoc loc,
ArrayRef<FormatElement *> arguments) override ;
// / Verify the elements of an optional group.
LogicalResult
verifyOptionalGroupElements (SMLoc loc, ArrayRef<FormatElement *> elements,
Optional< unsigned > anchorIndex ) override ;
LogicalResult verifyOptionalGroupElements (SMLoc loc,
ArrayRef<FormatElement *> elements,
FormatElement *anchor ) override ;
LogicalResult verifyOptionalGroupElement (SMLoc loc, FormatElement *element,
bool isAnchor);
Expand Down
Expand Up
@@ -3150,13 +3168,10 @@ OpFormatParser::parseTypeDirectiveOperand(SMLoc loc, bool isRefChild) {
return element;
}
LogicalResult
OpFormatParser::verifyOptionalGroupElements (SMLoc loc,
ArrayRef<FormatElement *> elements,
Optional<unsigned > anchorIndex) {
for (auto &it : llvm::enumerate (elements)) {
if (failed (verifyOptionalGroupElement (
loc, it.value (), anchorIndex && *anchorIndex == it.index ())))
LogicalResult OpFormatParser::verifyOptionalGroupElements (
SMLoc loc, ArrayRef<FormatElement *> elements, FormatElement *anchor) {
for (FormatElement *element : elements) {
if (failed (verifyOptionalGroupElement (loc, element, element == anchor)))
return failure ();
}
return success ();
Expand Down