[Mlir-commits] [mlir] [mlir] Add support for recursive elements in DICompositeTypeAttr. (PR #74948)
Tobias Gysi
llvmlistbot at llvm.org
Mon Dec 11 02:40:20 PST 2023
================
@@ -248,3 +251,340 @@ TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) {
return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
getAttributeName());
}
+
+//===----------------------------------------------------------------------===//
+// DICompositeTypeAttr
+//===----------------------------------------------------------------------===//
+
+DICompositeTypeAttr
+DICompositeTypeAttr::get(MLIRContext *context, unsigned tag, StringAttr name,
+ DIFileAttr file, uint32_t line, DIScopeAttr scope,
+ DITypeAttr baseType, DIFlags flags,
+ uint64_t sizeInBits, uint64_t alignInBits,
+ ::llvm::ArrayRef<DINodeAttr> elements) {
+ return Base::get(context, tag, name, file, line, scope, baseType, flags,
+ sizeInBits, alignInBits, elements, DistinctAttr());
+}
+
+DICompositeTypeAttr DICompositeTypeAttr::get(
+ MLIRContext *context, DistinctAttr identifier, unsigned tag,
+ StringAttr name, DIFileAttr file, uint32_t line, DIScopeAttr scope,
+ DITypeAttr baseType, DIFlags flags, uint64_t sizeInBits,
+ uint64_t alignInBits, ::llvm::ArrayRef<DINodeAttr> elements) {
+ return Base::get(context, tag, name, file, line, scope, baseType, flags,
+ sizeInBits, alignInBits, elements, identifier);
+}
+
+unsigned DICompositeTypeAttr::getTag() const { return getImpl()->getTag(); }
+
+StringAttr DICompositeTypeAttr::getName() const { return getImpl()->getName(); }
+
+DIFileAttr DICompositeTypeAttr::getFile() const { return getImpl()->getFile(); }
+
+uint32_t DICompositeTypeAttr::getLine() const { return getImpl()->getLine(); }
+
+DIScopeAttr DICompositeTypeAttr::getScope() const {
+ return getImpl()->getScope();
+}
+
+DITypeAttr DICompositeTypeAttr::getBaseType() const {
+ return getImpl()->getBaseType();
+}
+
+DIFlags DICompositeTypeAttr::getFlags() const { return getImpl()->getFlags(); }
+
+uint64_t DICompositeTypeAttr::getSizeInBits() const {
+ return getImpl()->getSizeInBits();
+}
+
+uint64_t DICompositeTypeAttr::getAlignInBits() const {
+ return getImpl()->getAlignInBits();
+}
+
+::llvm::ArrayRef<DINodeAttr> DICompositeTypeAttr::getElements() const {
+ return getImpl()->getElements();
+}
+
+DistinctAttr DICompositeTypeAttr::getIdentifier() const {
+ return getImpl()->getIdentifier();
+}
+
+Attribute DICompositeTypeAttr::parse(AsmParser &parser, Type type) {
+ FailureOr<AsmParser::CyclicParseReset> cyclicParse;
+ FailureOr<unsigned> tag;
+ FailureOr<StringAttr> name;
+ FailureOr<DIFileAttr> file;
+ FailureOr<uint32_t> line;
+ FailureOr<DIScopeAttr> scope;
+ FailureOr<DITypeAttr> baseType;
+ FailureOr<DIFlags> flags;
+ FailureOr<uint64_t> sizeInBits;
+ FailureOr<uint64_t> alignInBits;
+ SmallVector<DINodeAttr> elements;
+ DistinctAttr identifier;
+ const Location loc = parser.getEncodedSourceLoc(parser.getCurrentLocation());
+
+ auto paramParser = [&]() -> LogicalResult {
+ StringRef paramKey;
+ if (parser.parseKeyword(¶mKey)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected parameter name.");
+ }
+
+ if (parser.parseEqual()) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected `=` following parameter name.");
+ }
+
+ if (paramKey == "tag") {
+ tag = [&]() -> FailureOr<unsigned> {
+ StringRef nameKeyword;
+ if (parser.parseKeyword(&nameKeyword))
+ return failure();
+ if (const unsigned value = llvm::dwarf::getTag(nameKeyword))
+ return value;
+ return parser.emitError(parser.getCurrentLocation())
+ << "invalid debug info debug info tag name: " << nameKeyword;
+ }();
+ } else if (failed(name) && paramKey == "name") {
+ name = FieldParser<StringAttr>::parse(parser);
+ if (failed(name)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'name'");
+ }
+ } else if (failed(file) && paramKey == "file") {
+ file = FieldParser<DIFileAttr>::parse(parser);
+ if (failed(file)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'file'");
+ }
+ } else if (failed(line) && paramKey == "line") {
+ line = FieldParser<uint32_t>::parse(parser);
+ if (failed(line)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'line'");
+ }
+ } else if (failed(scope) && paramKey == "scope") {
+ scope = FieldParser<DIScopeAttr>::parse(parser);
+ if (failed(scope)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'scope'");
+ }
+ } else if (failed(baseType) && paramKey == "baseType") {
+ baseType = FieldParser<DITypeAttr>::parse(parser);
+ if (failed(baseType)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'baseType'");
+ }
+ } else if (failed(flags) && paramKey == "flags") {
+ flags = FieldParser<DIFlags>::parse(parser);
+ if (failed(flags)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'flags'");
+ }
+ } else if (failed(sizeInBits) && paramKey == "sizeInBits") {
+ sizeInBits = FieldParser<uint32_t>::parse(parser);
+ if (failed(sizeInBits)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'sizeInBits'");
+ }
+ } else if (failed(alignInBits) && paramKey == "alignInBits") {
+ alignInBits = FieldParser<uint32_t>::parse(parser);
+ if (failed(alignInBits)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse parameter 'alignInBits'");
+ }
+ } else {
+ return parser.emitError(parser.getCurrentLocation(),
+ "unknown parameter '")
+ << paramKey << "'";
+ }
+ return success();
+ };
+
+ // Begin parsing.
+ if (parser.parseLess()) {
+ parser.emitError(parser.getCurrentLocation(), "expected `<`");
+ return {};
+ }
+
+ // First, attempt to parse the identifier attribute.
+ const OptionalParseResult idResult =
+ parser.parseOptionalAttribute(identifier);
+ if (idResult.has_value() && succeeded(*idResult)) {
+ if (succeeded(parser.parseOptionalGreater())) {
+ DICompositeTypeAttr result =
+ getIdentified(parser.getContext(), identifier);
+ // Cyclic parsing should not initiate with only the identifier. Only
+ // nested instances should terminate early.
+ if (succeeded(parser.tryStartCyclicParse(result))) {
+ parser.emitError(parser.getCurrentLocation(),
+ "Expected identified attribute to contain at least "
+ "one other parameter");
+ return {};
+ }
+ return result;
+ }
+
+ if (parser.parseComma()) {
+ parser.emitError(parser.getCurrentLocation(), "Expected `,`");
+ }
+ }
+
+ // Parse immutable parameters.
+ if (parser.parseCommaSeparatedList(paramParser)) {
+ return {};
+ }
+
+ if (identifier) {
+ // Create the identified attribute.
+ DICompositeTypeAttr result =
+ get(parser.getContext(), identifier, tag.value_or(0),
+ name.value_or(StringAttr()), file.value_or(DIFileAttr()),
+ line.value_or(0), scope.value_or(DIScopeAttr()),
+ baseType.value_or(DITypeAttr()), flags.value_or(DIFlags::Zero),
+ sizeInBits.value_or(0), alignInBits.value_or(0));
+
+ // Initiate cyclic parsing.
+ if (cyclicParse = parser.tryStartCyclicParse(result); failed(cyclicParse)) {
+ return {};
+ }
+ }
+
+ // Parse the elements now.
+ if (succeeded(parser.parseOptionalLParen())) {
+ if (parser.parseCommaSeparatedList([&]() -> LogicalResult {
+ Attribute attr;
+ if (parser.parseAttribute(attr)) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected attribute");
+ }
+ elements.push_back(mlir::cast<DINodeAttr>(attr));
+ return success();
+ })) {
+ return {};
+ }
+
+ if (parser.parseRParen()) {
+ parser.emitError(parser.getCurrentLocation(), "expected `)");
+ return {};
+ }
+ }
+
+ // Expect the attribute to terminate.
+ if (parser.parseGreater()) {
+ parser.emitError(parser.getCurrentLocation(), "expected `>`");
+ return {};
+ }
+
+ if (!identifier)
+ return get(loc.getContext(), tag.value_or(0), name.value_or(StringAttr()),
+ file.value_or(DIFileAttr()), line.value_or(0),
+ scope.value_or(DIScopeAttr()), baseType.value_or(DITypeAttr()),
+ flags.value_or(DIFlags::Zero), sizeInBits.value_or(0),
+ alignInBits.value_or(0), elements);
+
+ // Replace the elements if the attribute is identified.
+ DICompositeTypeAttr result = getIdentified(parser.getContext(), identifier);
+ result.replaceElements(elements);
+ return result;
+}
+
+void DICompositeTypeAttr::print(AsmPrinter &printer) const {
+ FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrint;
+ SmallVector<std::function<void()>> valuePrinters;
+
+ printer << "<";
+ if (getImpl()->isIdentified()) {
+ cyclicPrint = printer.tryStartCyclicPrint(*this);
+ if (failed(cyclicPrint)) {
+ printer << getIdentifier() << ">";
+ return;
+ }
+ valuePrinters.push_back([&]() { printer << getIdentifier(); });
+ }
+
+ if (getTag() > 0) {
+ valuePrinters.push_back(
+ [&]() { printer << "tag = " << llvm::dwarf::TagString(getTag()); });
+ }
+
+ if (getName()) {
+ valuePrinters.push_back([&]() {
+ printer << "name = ";
+ printer.printStrippedAttrOrType(getName());
+ });
+ }
+
+ if (getFile()) {
+ valuePrinters.push_back([&]() {
+ printer << "file = ";
+ printer.printStrippedAttrOrType(getFile());
+ });
+ }
+
+ if (getLine() > 0) {
+ valuePrinters.push_back([&]() {
+ printer << "line = ";
+ printer.printStrippedAttrOrType(getLine());
+ });
+ }
+
+ if (getScope()) {
+ valuePrinters.push_back([&]() {
+ printer << "scope = ";
+ printer.printStrippedAttrOrType(getScope());
+ });
+ }
+
+ if (getBaseType()) {
+ valuePrinters.push_back([&]() {
+ printer << "baseType = ";
+ printer.printStrippedAttrOrType(getBaseType());
+ });
+ }
+
+ if (getFlags() != DIFlags::Zero) {
+ valuePrinters.push_back([&]() {
+ printer << "flags = ";
+ printer.printStrippedAttrOrType(getFlags());
+ });
+ }
+
+ if (getSizeInBits() > 0) {
+ valuePrinters.push_back([&]() {
+ printer << "sizeInBits = ";
+ printer.printStrippedAttrOrType(getSizeInBits());
+ });
+ }
+
+ if (getAlignInBits() > 0) {
+ valuePrinters.push_back([&]() {
+ printer << "alignInBits = ";
+ printer.printStrippedAttrOrType(getAlignInBits());
+ });
+ }
+ interleaveComma(valuePrinters, printer,
+ [&](const std::function<void()> &fn) { fn(); });
+
+ if (!getElements().empty()) {
+ printer << " (";
+ printer.printStrippedAttrOrType(getElements());
+ printer << ")";
+ }
+
+ printer << ">";
+}
+
+DICompositeTypeAttr
+DICompositeTypeAttr::getIdentified(MLIRContext *context,
----------------
gysit wrote:
I guess this function is worth a comment that explains we use it to lookup an **existing** identified attribute and that is why we can pass in null values for anything except for the distinct attribute. I assume there is now way to assert here that the attribute actually has been created before with real payload? Or am I misunderstanding something?
https://github.com/llvm/llvm-project/pull/74948
More information about the Mlir-commits
mailing list