diff --git a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp --- a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp +++ b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp @@ -53,18 +53,43 @@ return LLVM::LLVMPointerType::get(pointee, type.getAddressSpace()); return llvm::None; }); - addConversion([&](LLVM::LLVMStructType type) -> llvm::Optional { - // TODO: handle conversion of identified structs, which may be recursive. - if (type.isIdentified()) - return type; + addConversion([&](LLVM::LLVMStructType type, SmallVectorImpl &results, + ArrayRef callStack) -> llvm::Optional { + if (type.isIdentified()) { + auto convertedType = LLVM::LLVMStructType::getIdentified( + type.getContext(), ("_Converted_" + type.getName()).str()); + unsigned counter = 1; + while (convertedType.isInitialized()) { + assert(counter != UINT_MAX && + "about to overflow struct renaming counter in conversion"); + convertedType = LLVM::LLVMStructType::getIdentified( + type.getContext(), + ("_Converted_" + std::to_string(counter) + type.getName()).str()); + } + if (llvm::count(callStack, type) > 1) { + results.push_back(convertedType); + return success(); + } + + SmallVector convertedElemTypes; + convertedElemTypes.reserve(type.getBody().size()); + if (failed(convertTypes(type.getBody(), convertedElemTypes))) + return llvm::None; + + if (failed(convertedType.setBody(convertedElemTypes, type.isPacked()))) + return failure(); + results.push_back(convertedType); + return success(); + } SmallVector convertedSubtypes; convertedSubtypes.reserve(type.getBody().size()); if (failed(convertTypes(type.getBody(), convertedSubtypes))) return llvm::None; - return LLVM::LLVMStructType::getLiteral(type.getContext(), - convertedSubtypes, type.isPacked()); + results.push_back(LLVM::LLVMStructType::getLiteral( + type.getContext(), convertedSubtypes, type.isPacked())); + return success(); }); addConversion([&](LLVM::LLVMArrayType type) -> llvm::Optional { if (auto element = convertType(type.getElementType())) diff --git a/mlir/test/Conversion/StandardToLLVM/convert-types.mlir b/mlir/test/Conversion/StandardToLLVM/convert-types.mlir --- a/mlir/test/Conversion/StandardToLLVM/convert-types.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-types.mlir @@ -13,7 +13,7 @@ func private @struct_ptr() -> !llvm.struct<(ptr)> // CHECK-LABEL: @named_struct_ptr() -// CHECK: !llvm.struct<"named", (ptr)> +// CHECK: !llvm.struct<"_Converted_named", (ptr)> func private @named_struct_ptr() -> !llvm.struct<"named", (ptr)> // CHECK-LABEL: @array_ptr() @@ -26,6 +26,6 @@ // TODO: support conversion of recursive types in the conversion infra. // CHECK-LABEL: @named_recursive() -// CHECK: !llvm.struct<"recursive", (ptr, ptr>)> +// CHECK: !llvm.struct<"_Converted_recursive", (ptr, ptr>)> func private @named_recursive() -> !llvm.struct<"recursive", (ptr, ptr>)>