diff --git a/mlir/include/mlir/Support/IndentedOstream.h b/mlir/include/mlir/Support/IndentedOstream.h --- a/mlir/include/mlir/Support/IndentedOstream.h +++ b/mlir/include/mlir/Support/IndentedOstream.h @@ -85,11 +85,11 @@ } private: - void write_impl(const char *ptr, size_t size) override; + void write_impl(const char *ptr, size_t size) final; /// Return the current position within the stream, not counting the bytes /// currently in the buffer. - uint64_t current_pos() const override { return os.tell(); } + uint64_t current_pos() const final { return os.tell(); } /// Constant indent added/removed. static constexpr int indentSize = 2; @@ -110,5 +110,70 @@ raw_ostream &os; }; +inline raw_indented_ostream & +mlir::raw_indented_ostream::printReindented(StringRef str, + StringRef extraPrefix) { + StringRef output = str; + // Skip empty lines. + while (!output.empty()) { + auto split = output.split('\n'); + size_t indent = split.first.find_first_not_of(" \t"); + if (indent != StringRef::npos) { + // Set an initial value. + leadingWs = indent; + break; + } + output = split.second; + } + // Determine the maximum indent. + StringRef remaining = output; + while (!remaining.empty()) { + auto split = remaining.split('\n'); + size_t indent = split.first.find_first_not_of(" \t"); + if (indent != StringRef::npos) + leadingWs = std::min(leadingWs, static_cast(indent)); + remaining = split.second; + } + // Print, skipping the empty lines. + std::swap(currentExtraPrefix, extraPrefix); + *this << output; + std::swap(currentExtraPrefix, extraPrefix); + leadingWs = 0; + return *this; +} + +inline void mlir::raw_indented_ostream::write_impl(const char *ptr, + size_t size) { + StringRef str(ptr, size); + // Print out indented. + auto print = [this](StringRef str) { + if (atStartOfLine) + os.indent(currentIndent) << currentExtraPrefix << str.substr(leadingWs); + else + os << str.substr(leadingWs); + }; + + while (!str.empty()) { + size_t idx = str.find('\n'); + if (idx == StringRef::npos) { + if (!str.substr(leadingWs).empty()) { + print(str); + atStartOfLine = false; + } + break; + } + + auto split = + std::make_pair(str.slice(0, idx), str.slice(idx + 1, StringRef::npos)); + // Print empty new line without spaces if line only has spaces and no extra + // prefix is requested. + if (!split.first.ltrim().empty() || !currentExtraPrefix.empty()) + print(split.first); + os << '\n'; + atStartOfLine = true; + str = split.second; + } +} + } // namespace mlir #endif // MLIR_SUPPORT_INDENTEDOSTREAM_H_ diff --git a/mlir/lib/Support/CMakeLists.txt b/mlir/lib/Support/CMakeLists.txt --- a/mlir/lib/Support/CMakeLists.txt +++ b/mlir/lib/Support/CMakeLists.txt @@ -1,6 +1,5 @@ set(LLVM_OPTIONAL_SOURCES FileUtilities.cpp - IndentedOstream.cpp InterfaceSupport.cpp StorageUniquer.cpp Timing.cpp @@ -10,7 +9,6 @@ add_mlir_library(MLIRSupport FileUtilities.cpp - IndentedOstream.cpp InterfaceSupport.cpp StorageUniquer.cpp Timing.cpp @@ -22,14 +20,3 @@ LINK_LIBS PUBLIC ${LLVM_PTHREAD_LIB}) - -# This doesn't use add_mlir_library as it is used in mlir-tblgen and else -# mlir-tblgen ends up depending on mlir-generic-headers. -add_llvm_library(MLIRSupportIndentedOstream - IndentedOstream.cpp - - DISABLE_LLVM_LINK_LLVM_DYLIB - - LINK_COMPONENTS - Support - ) diff --git a/mlir/lib/Support/IndentedOstream.cpp b/mlir/lib/Support/IndentedOstream.cpp deleted file mode 100644 --- a/mlir/lib/Support/IndentedOstream.cpp +++ /dev/null @@ -1,80 +0,0 @@ -//===- IndentedOstream.cpp - raw ostream wrapper to indent ----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// raw_ostream subclass that keeps track of indentation for textual output -// where indentation helps readability. -// -//===----------------------------------------------------------------------===// - -#include "mlir/Support/IndentedOstream.h" - -using namespace mlir; - -raw_indented_ostream & -mlir::raw_indented_ostream::printReindented(StringRef str, - StringRef extraPrefix) { - StringRef output = str; - // Skip empty lines. - while (!output.empty()) { - auto split = output.split('\n'); - size_t indent = split.first.find_first_not_of(" \t"); - if (indent != StringRef::npos) { - // Set an initial value. - leadingWs = indent; - break; - } - output = split.second; - } - // Determine the maximum indent. - StringRef remaining = output; - while (!remaining.empty()) { - auto split = remaining.split('\n'); - size_t indent = split.first.find_first_not_of(" \t"); - if (indent != StringRef::npos) - leadingWs = std::min(leadingWs, static_cast(indent)); - remaining = split.second; - } - // Print, skipping the empty lines. - std::swap(currentExtraPrefix, extraPrefix); - *this << output; - std::swap(currentExtraPrefix, extraPrefix); - leadingWs = 0; - return *this; -} - -void mlir::raw_indented_ostream::write_impl(const char *ptr, size_t size) { - StringRef str(ptr, size); - // Print out indented. - auto print = [this](StringRef str) { - if (atStartOfLine) - os.indent(currentIndent) << currentExtraPrefix << str.substr(leadingWs); - else - os << str.substr(leadingWs); - }; - - while (!str.empty()) { - size_t idx = str.find('\n'); - if (idx == StringRef::npos) { - if (!str.substr(leadingWs).empty()) { - print(str); - atStartOfLine = false; - } - break; - } - - auto split = - std::make_pair(str.slice(0, idx), str.slice(idx + 1, StringRef::npos)); - // Print empty new line without spaces if line only has spaces and no extra - // prefix is requested. - if (!split.first.ltrim().empty() || !currentExtraPrefix.empty()) - print(split.first); - os << '\n'; - atStartOfLine = true; - str = split.second; - } -} diff --git a/mlir/lib/TableGen/CMakeLists.txt b/mlir/lib/TableGen/CMakeLists.txt --- a/mlir/lib/TableGen/CMakeLists.txt +++ b/mlir/lib/TableGen/CMakeLists.txt @@ -7,7 +7,10 @@ # libMLIR.so in some contexts (see unittests/Tablegen, for instance, which # has a dependence on MLIRIR, which must depend on libLLVM.so). This works # in this special case because this library is static. - +# +# In order for this arrangement to be sound, it must not depend on libraries +# that may be transitively included in libMLIR.so or libLLVM.so. Specifically, +# this means that MLIRSupport (outside of header-only access) cannot be used. llvm_add_library(MLIRTableGen STATIC Argument.cpp Attribute.cpp @@ -35,6 +38,7 @@ ADDITIONAL_HEADER_DIRS ${MLIR_MAIN_INCLUDE_DIR}/mlir/TableGen + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Support ) mlir_check_all_link_libraries(MLIRTableGen) diff --git a/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt b/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt --- a/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt +++ b/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt @@ -1,3 +1,5 @@ +# See notes in lib/TableGen/CMakeLists.txt regarding why this library is +# declared as it is. The same dependency rules apply. llvm_add_library(MLIRTblgenLib STATIC MlirTblgenMain.cpp diff --git a/mlir/tools/mlir-tblgen/CMakeLists.txt b/mlir/tools/mlir-tblgen/CMakeLists.txt --- a/mlir/tools/mlir-tblgen/CMakeLists.txt +++ b/mlir/tools/mlir-tblgen/CMakeLists.txt @@ -35,7 +35,6 @@ set_target_properties(mlir-tblgen PROPERTIES FOLDER "Tablegenning") target_link_libraries(mlir-tblgen PRIVATE - MLIRSupportIndentedOstream MLIRTblgenLib) mlir_check_all_link_libraries(mlir-tblgen)