diff --git a/mlir/examples/standalone/CMakeLists.txt b/mlir/examples/standalone/CMakeLists.txt --- a/mlir/examples/standalone/CMakeLists.txt +++ b/mlir/examples/standalone/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) -set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to") +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") find_package(MLIR REQUIRED CONFIG) diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h --- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h +++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h @@ -52,10 +52,8 @@ template void allowDialect() { // The following expands a call to allowDialectImpl for each dialect - // in 'DialectTs'. This magic is necessary due to a limitation in the places - // that a parameter pack can be expanded in c++11. - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{0, (allowDialectImpl(), 0)...}; + // in 'DialectTs'. + (allowDialectImpl(), ...); } /// Deny the given dialects. @@ -63,8 +61,7 @@ /// This function adds one or multiple DENY entries. template void denyDialect() { - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{0, (denyDialectImpl(), 0)...}; + (denyDialectImpl(), ...); } /// Allow the given dialect. @@ -82,8 +79,7 @@ /// This function adds one or multiple ALLOW entries. template void allowOperation() { - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{0, (allowOperationImpl(), 0)...}; + (allowOperationImpl(), ...); } /// Deny the given ops. @@ -91,8 +87,7 @@ /// This function adds one or multiple DENY entries. template void denyOperation() { - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{0, (denyOperationImpl(), 0)...}; + (denyOperationImpl(), ...); } /// Allow the given op. diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td @@ -334,13 +334,10 @@ /// dialect. Checks that they implement the required interfaces. template void addOperationsChecked() { - (void)std::initializer_list{(addOperationIfNotRegistered(), - 0)...}; + (addOperationIfNotRegistered(),...); #ifndef NDEBUG - (void)std::initializer_list{ - (detail::checkImplementsTransformInterface(getContext()), - 0)...}; + (detail::checkImplementsTransformInterface(getContext()),...); #endif // NDEBUG } diff --git a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h --- a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h +++ b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h @@ -172,9 +172,7 @@ llvm::SmallVector argsArray; // Pack every arguments in an array of pointers. Delegate the packing to a // trait so that it can be overridden per argument type. - // TODO: replace with a fold expression when migrating to C++17. - int dummy[] = {0, ((void)Argument::pack(argsArray, args), 0)...}; - (void)dummy; + (Argument::pack(argsArray, args), ...); return invokePacked(adapterName, argsArray); } diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h --- a/mlir/include/mlir/IR/BuiltinAttributes.h +++ b/mlir/include/mlir/IR/BuiltinAttributes.h @@ -84,7 +84,6 @@ /// Type trait used to check if the given type T is a potentially valid C++ /// floating point type that can be used to access the underlying element /// types of a DenseElementsAttr. - // TODO: Use std::disjunction when C++17 is supported. template struct is_valid_cpp_fp_type { /// The type is a valid floating point type if it is a builtin floating diff --git a/mlir/include/mlir/IR/BuiltinTypes.td b/mlir/include/mlir/IR/BuiltinTypes.td --- a/mlir/include/mlir/IR/BuiltinTypes.td +++ b/mlir/include/mlir/IR/BuiltinTypes.td @@ -262,7 +262,7 @@ /// Integer representation maximal bitwidth. /// Note: This is aligned with the maximum width of llvm::IntegerType. - static constexpr unsigned kMaxWidth = (1 << 24) - 1; + static constexpr inline unsigned kMaxWidth = (1 << 24) - 1; }]; } diff --git a/mlir/include/mlir/IR/Dialect.h b/mlir/include/mlir/IR/Dialect.h --- a/mlir/include/mlir/IR/Dialect.h +++ b/mlir/include/mlir/IR/Dialect.h @@ -186,8 +186,7 @@ /// Register a set of dialect interfaces with this dialect instance. template void addInterfaces() { - (void)std::initializer_list{ - 0, (addInterface(std::make_unique(this)), 0)...}; + (addInterface(std::make_unique(this)), ...); } template InterfaceT &addInterface(Args &&...args) { @@ -210,6 +209,10 @@ /// template void addOperations() { + // This initializer_list argument pack expansion is essentially equal to + // using a fold expression with a comma operator. Clang however, refuses + // to compile a fold expression with a depth of more than 256 by default. + // There seem to be no such limitations for initializer_list. (void)std::initializer_list{ 0, (RegisteredOperationName::insert(*this), 0)...}; } @@ -217,7 +220,7 @@ /// Register a set of type classes with this dialect. template void addTypes() { - (void)std::initializer_list{0, (addType(), 0)...}; + (addType(), ...); } /// Register a type instance with this dialect. @@ -228,7 +231,7 @@ /// Register a set of attribute classes with this dialect. template void addAttributes() { - (void)std::initializer_list{0, (addAttribute(), 0)...}; + (addAttribute(), ...); } /// Register an attribute instance with this dialect. diff --git a/mlir/include/mlir/IR/DialectRegistry.h b/mlir/include/mlir/IR/DialectRegistry.h --- a/mlir/include/mlir/IR/DialectRegistry.h +++ b/mlir/include/mlir/IR/DialectRegistry.h @@ -175,8 +175,7 @@ /// Add the given extensions to the registry. template void addExtensions() { - (void)std::initializer_list{ - (addExtension(std::make_unique()), 0)...}; + (addExtension(std::make_unique()), ...); } /// Add an extension function that requires the given dialects. diff --git a/mlir/include/mlir/IR/Matchers.h b/mlir/include/mlir/IR/Matchers.h --- a/mlir/include/mlir/IR/Matchers.h +++ b/mlir/include/mlir/IR/Matchers.h @@ -224,10 +224,9 @@ template constexpr void enumerateImpl(TupleT &&tuple, CallbackT &&callback, std::index_sequence) { - (void)std::initializer_list{ - 0, - (callback(std::integral_constant{}, std::get(tuple)), - 0)...}; + + (callback(std::integral_constant{}, std::get(tuple)), + ...); } template diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -1492,12 +1492,10 @@ template using detect_has_fold_trait = llvm::is_detected; /// Trait to check if T provides any `foldTrait` method. -/// NOTE: This should use std::disjunction when C++17 is available. template using detect_has_any_fold_trait = - std::conditional_t::value), - detect_has_fold_trait, - detect_has_single_result_fold_trait>; + std::disjunction, + detect_has_single_result_fold_trait>; /// Returns the result of folding a trait that implements a `foldTrait` function /// that is specialized for operations that have a single result. @@ -1543,10 +1541,7 @@ template static LogicalResult foldTraits(Operation *op, ArrayRef operands, SmallVectorImpl &results) { - bool anyFolded = false; - (void)std::initializer_list{ - (anyFolded |= succeeded(foldTrait(op, operands, results)), 0)...}; - return success(anyFolded); + return success((succeeded(foldTrait(op, operands, results)) | ...)); } //===----------------------------------------------------------------------===// @@ -1581,10 +1576,7 @@ /// Given a set of traits, return the result of verifying the given operation. template LogicalResult verifyTraits(Operation *op) { - LogicalResult result = success(); - (void)std::initializer_list{ - (result = succeeded(result) ? verifyTrait(op) : failure(), 0)...}; - return result; + return success((succeeded(verifyTrait(op)) && ...)); } /// Verify the given trait if it provides a region verifier. @@ -1604,12 +1596,7 @@ /// given operation. template LogicalResult verifyRegionTraits(Operation *op) { - (void)op; - LogicalResult result = success(); - (void)std::initializer_list{ - (result = succeeded(result) ? verifyRegionTrait(op) : failure(), - 0)...}; - return result; + return success((succeeded(verifyRegionTrait(op)) && ...)); } } // namespace op_definition_impl @@ -1695,7 +1682,7 @@ llvm::report_fatal_error( "Attempting to attach an interface to an unregistered operation " + ConcreteType::getOperationName() + "."); - (void)std::initializer_list{(checkInterfaceTarget(), 0)...}; + (checkInterfaceTarget(), ...); info->attachInterface(); } diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -1079,15 +1079,10 @@ auto errorFn = [&](const Twine &msg) { return rewriter.notifyMatchFailure(rewriter.getUnknownLoc(), msg); }; - LogicalResult result = success(); - (void)std::initializer_list{ - (result = - succeeded(result) - ? ProcessPDLValue>:: - verifyAsArg(errorFn, values[I], I) - : failure(), - 0)...}; - return result; + return success( + (succeeded(ProcessPDLValue>:: + verifyAsArg(errorFn, values[I], I)) && + ...)); } /// Assert that the given PDLValues match the constraints defined by the @@ -1102,10 +1097,10 @@ auto errorFn = [&](const Twine &msg) -> LogicalResult { llvm::report_fatal_error(msg); }; - (void)std::initializer_list{ - (assert(succeeded(ProcessPDLValue>::verifyAsArg(errorFn, values[I], I))), - 0)...}; + (assert(succeeded( + ProcessPDLValue>::verifyAsArg( + errorFn, values[I], I))), + ...); #endif } @@ -1134,10 +1129,7 @@ static void processResults(PatternRewriter &rewriter, PDLResultList &results, std::tuple &&tuple) { auto applyFn = [&](auto &&...args) { - // TODO: Use proper fold expressions when we have C++17. For now we use a - // bogus std::initializer_list to work around C++14 limitations. - (void)std::initializer_list{ - (processResults(rewriter, results, std::move(args)), 0)...}; + (processResults(rewriter, results, std::move(args)), ...); }; llvm::apply_tuple(applyFn, std::move(tuple)); } @@ -1412,14 +1404,10 @@ typename = std::enable_if_t> RewritePatternSet &add(ConstructorArg &&arg, ConstructorArgs &&...args) { // The following expands a call to emplace_back for each of the pattern - // types 'Ts'. This magic is necessary due to a limitation in the places - // that a parameter pack can be expanded in c++11. - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{ - 0, (addImpl(/*debugLabels=*/llvm::None, - std::forward(arg), - std::forward(args)...), - 0)...}; + // types 'Ts'. + (addImpl(/*debugLabels=*/llvm::None, std::forward(arg), + std::forward(args)...), + ...); return *this; } /// An overload of the above `add` method that allows for attaching a set @@ -1433,11 +1421,8 @@ ConstructorArg &&arg, ConstructorArgs &&...args) { // The following expands a call to emplace_back for each of the pattern - // types 'Ts'. This magic is necessary due to a limitation in the places - // that a parameter pack can be expanded in c++11. - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{ - 0, (addImpl(debugLabels, arg, args...), 0)...}; + // types 'Ts'. + (addImpl(debugLabels, arg, args...), ...); return *this; } @@ -1445,7 +1430,7 @@ /// `this` for chaining insertions. template RewritePatternSet &add() { - (void)std::initializer_list{0, (addImpl(), 0)...}; + (addImpl(), ...); return *this; } @@ -1498,11 +1483,8 @@ typename = std::enable_if_t> RewritePatternSet &insert(ConstructorArg &&arg, ConstructorArgs &&...args) { // The following expands a call to emplace_back for each of the pattern - // types 'Ts'. This magic is necessary due to a limitation in the places - // that a parameter pack can be expanded in c++11. - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{ - 0, (addImpl(/*debugLabels=*/llvm::None, arg, args...), 0)...}; + // types 'Ts'. + (addImpl(/*debugLabels=*/llvm::None, arg, args...), ...); return *this; } @@ -1510,7 +1492,7 @@ /// `this` for chaining insertions. template RewritePatternSet &insert() { - (void)std::initializer_list{0, (addImpl(), 0)...}; + (addImpl(), ...); return *this; } diff --git a/mlir/include/mlir/IR/StorageUniquerSupport.h b/mlir/include/mlir/IR/StorageUniquerSupport.h --- a/mlir/include/mlir/IR/StorageUniquerSupport.h +++ b/mlir/include/mlir/IR/StorageUniquerSupport.h @@ -138,8 +138,8 @@ if (!abstract) llvm::report_fatal_error("Registering an interface for an attribute/type " "that is not itself registered."); - (void)std::initializer_list{ - (checkInterfaceTarget(), 0)...}; + + (checkInterfaceTarget(), ...); abstract->interfaceMap.template insert(); } diff --git a/mlir/include/mlir/Support/InterfaceSupport.h b/mlir/include/mlir/Support/InterfaceSupport.h --- a/mlir/include/mlir/Support/InterfaceSupport.h +++ b/mlir/include/mlir/Support/InterfaceSupport.h @@ -191,16 +191,14 @@ /// do not represent interfaces are not added to the interface map. template static InterfaceMap get() { - // TODO: Use constexpr if here in C++17. constexpr size_t numInterfaces = num_interface_types_t::value; - if (numInterfaces == 0) + if constexpr (numInterfaces == 0) return InterfaceMap(); std::array, numInterfaces> elements; std::pair *elementIt = elements.data(); (void)elementIt; - (void)std::initializer_list{ - 0, (addModelAndUpdateIterator(elementIt), 0)...}; + (addModelAndUpdateIterator(elementIt), ...); return InterfaceMap(elements); } diff --git a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp --- a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp +++ b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp @@ -178,15 +178,12 @@ } /// The minimum alignment to use with aligned_alloc (has to be a power of 2). - static constexpr uint64_t kMinAlignedAllocAlignment = 16UL; + static inline constexpr uint64_t kMinAlignedAllocAlignment = 16UL; /// Default layout to use in absence of the corresponding analysis. DataLayout defaultLayout; }; -// Out of line definition, required till C++17. -constexpr uint64_t AlignedAllocOpLowering::kMinAlignedAllocAlignment; - struct AllocaOpLowering : public AllocLikeOpLLVMLowering { AllocaOpLowering(LLVMTypeConverter &converter) : AllocLikeOpLLVMLowering(memref::AllocaOp::getOperationName(), diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp --- a/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp +++ b/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp @@ -96,8 +96,7 @@ template void addNamedOpBuilders( llvm::StringMap &map) { - (void)std::initializer_list{0, - (addNamedOpBuilderImpl(map), 0)...}; + (addNamedOpBuilderImpl(map), ...); } void mlir::linalg::LinalgDialect::initialize() { diff --git a/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp @@ -137,8 +137,7 @@ template struct LinalgOpInterfaceHelper { static void registerOpInterface(MLIRContext *ctx) { - (void)std::initializer_list{ - 0, (Ops::template attachInterface>(*ctx), 0)...}; + (Ops::template attachInterface>(*ctx), ...); } }; } // namespace diff --git a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp @@ -263,8 +263,7 @@ /// Variadic helper function. template static void registerAll(MLIRContext *ctx) { - // FIXME: In c++17 this can be simplified by using 'fold expressions'. - (void)std::initializer_list{0, (registerOne(ctx), 0)...}; + (registerOne(ctx), ...); } #define GET_OP_LIST diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaLayerwiseConstantFoldPass.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaLayerwiseConstantFoldPass.cpp --- a/mlir/lib/Dialect/Tosa/Transforms/TosaLayerwiseConstantFoldPass.cpp +++ b/mlir/lib/Dialect/Tosa/Transforms/TosaLayerwiseConstantFoldPass.cpp @@ -23,8 +23,7 @@ template void addOpsCanonicalizations(MLIRContext *ctx, RewritePatternSet &patterns) { - (void)std::initializer_list{ - 0, (Args::getCanonicalizationPatterns(patterns, ctx), 0)...}; + (Args::getCanonicalizationPatterns(patterns, ctx), ...); } void populateTosaOpsCanonicalizationPatterns(MLIRContext *ctx, diff --git a/mlir/lib/IR/BuiltinTypes.cpp b/mlir/lib/IR/BuiltinTypes.cpp --- a/mlir/lib/IR/BuiltinTypes.cpp +++ b/mlir/lib/IR/BuiltinTypes.cpp @@ -60,9 +60,6 @@ // Integer Type //===----------------------------------------------------------------------===// -// static constexpr must have a definition (until in C++17 and inline variable). -constexpr unsigned IntegerType::kMaxWidth; - /// Verify the construction of an integer type. LogicalResult IntegerType::verify(function_ref emitError, unsigned width,