[llvm-branch-commits] [flang] 352b872 - Add list input test to GTest suite
Author: Asher Mancinelli Date: 2021-03-30T11:16:23-07:00 New Revision: 352b872f8f717a98328eb48b57f0a4d83c686d9f URL: https://github.com/llvm/llvm-project/commit/352b872f8f717a98328eb48b57f0a4d83c686d9f DIFF: https://github.com/llvm/llvm-project/commit/352b872f8f717a98328eb48b57f0a4d83c686d9f.diff LOG: Add list input test to GTest suite Added: flang/unittests/RuntimeGTest/ListInputTest.cpp Modified: flang/unittests/RuntimeGTest/CMakeLists.txt Removed: diff --git a/flang/unittests/RuntimeGTest/CMakeLists.txt b/flang/unittests/RuntimeGTest/CMakeLists.txt index d4ad6b2e15201..3e48b67f5a098 100644 --- a/flang/unittests/RuntimeGTest/CMakeLists.txt +++ b/flang/unittests/RuntimeGTest/CMakeLists.txt @@ -5,6 +5,7 @@ add_flang_unittest(FlangRuntimeTests NumericalFormatTest.cpp RuntimeCrashTest.cpp CrashHandlerFixture.cpp + ListInputTest.cpp ) target_link_libraries(FlangRuntimeTests diff --git a/flang/unittests/RuntimeGTest/ListInputTest.cpp b/flang/unittests/RuntimeGTest/ListInputTest.cpp new file mode 100644 index 0..f1f62197ae07e --- /dev/null +++ b/flang/unittests/RuntimeGTest/ListInputTest.cpp @@ -0,0 +1,76 @@ +//===-- flang/unittests/RuntimeGTest/ListInputTest.cpp --*- C++ -*-===// +// +// 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 +// +//===--===// + +#include "CrashHandlerFixture.h" +#include "../../runtime/descriptor.h" +#include "../../runtime/io-api.h" +#include "../../runtime/io-error.h" + +using namespace Fortran::runtime; +using namespace Fortran::runtime::io; + +// Pads characters with whitespace when needed +void SetCharacter(char *to, std::size_t n, const char *from) { + auto len{std::strlen(from)}; + std::memcpy(to, from, std::min(len, n)); + if (len < n) { +std::memset(to + len, ' ', n - len); + } +} + +struct InputTest : CrashHandlerFixture {}; + +TEST(InputTest, TestListInput) { + static constexpr int numBuffers{4}; + static constexpr int maxBufferLength{32}; + static char buffer[numBuffers][maxBufferLength]; + int j{0}; + for (const char *p : {"1 2 2*3 ,", ",6,,8,1*", + "2*'abcdefghijklmnopqrstuvwxyzABC", "DEFGHIJKLMNOPQRSTUVWXYZ'"}) { +SetCharacter(buffer[j++], maxBufferLength, p); + } + + static StaticDescriptor<1> staticDescriptor; + static Descriptor &whole{staticDescriptor.descriptor()}; + static SubscriptValue extent[]{numBuffers}; + whole.Establish(TypeCode{CFI_type_char}, maxBufferLength, &buffer, 1, extent, + CFI_attribute_pointer); + whole.Dump(); + whole.Check(); + + static auto cookie{IONAME(BeginInternalArrayListInput)(whole)}; + static constexpr int listInputLength{9}; + static std::int64_t n[listInputLength]{-1, -2, -3, -4, 5, -6, 7, -8, 9}; + static const std::int64_t want[listInputLength]{1, 2, 3, 3, 5, 6, 7, 8, 9}; + for (j = 0; j < listInputLength; ++j) { +IONAME(InputInteger)(cookie, n[j]); + } + + static constexpr int numInputBuffers{2}; + static constexpr int inputBufferLength{54}; + static char inputBuffers[numInputBuffers][inputBufferLength]{}; + IONAME(InputAscii)(cookie, inputBuffers[0], inputBufferLength - 1); + IONAME(InputAscii)(cookie, inputBuffers[1], inputBufferLength - 1); + + static const auto status{IONAME(EndIoStatement)(cookie)}; + ASSERT_EQ(status, 0) << "list-directed input failed, status " + << static_cast(status) << '\n'; + + for (j = 0; j < listInputLength; ++j) { +ASSERT_EQ(n[j], want[j]) +<< "wanted n[" << j << "]==" << want[j] << ", got " << n[j] << '\n'; + } + + for (j = 0; j < numInputBuffers; ++j) { +ASSERT_EQ(std::strcmp(inputBuffers[j], + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "), +0) +<< "wanted asc[" << j << "]=alphabets, got '" << inputBuffers[j] << "'\n"; + } +} + ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] ee822a6 - Remove legacy list-input test
Author: Asher Mancinelli Date: 2021-03-30T11:25:42-07:00 New Revision: ee822a6bda40f6b17ba7b4c6d414827c665c9480 URL: https://github.com/llvm/llvm-project/commit/ee822a6bda40f6b17ba7b4c6d414827c665c9480 DIFF: https://github.com/llvm/llvm-project/commit/ee822a6bda40f6b17ba7b4c6d414827c665c9480.diff LOG: Remove legacy list-input test Added: Modified: flang/unittests/Runtime/CMakeLists.txt Removed: flang/unittests/Runtime/list-input.cpp diff --git a/flang/unittests/Runtime/CMakeLists.txt b/flang/unittests/Runtime/CMakeLists.txt index cc7ac72771839..03998fa55d143 100644 --- a/flang/unittests/Runtime/CMakeLists.txt +++ b/flang/unittests/Runtime/CMakeLists.txt @@ -37,11 +37,6 @@ add_flang_nongtest_unittest(external-io FortranRuntime ) -add_flang_nongtest_unittest(list-input - RuntimeTesting - FortranRuntime -) - add_flang_nongtest_unittest(buffer RuntimeTesting FortranRuntime diff --git a/flang/unittests/Runtime/list-input.cpp b/flang/unittests/Runtime/list-input.cpp deleted file mode 100644 index 9ec77080203a2..0 --- a/flang/unittests/Runtime/list-input.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Basic sanity tests for list-directed input - -#include "testing.h" -#include "../../runtime/descriptor.h" -#include "../../runtime/io-api.h" -#include "../../runtime/io-error.h" -#include -#include - -using namespace Fortran::runtime; -using namespace Fortran::runtime::io; - -int main() { - StartTests(); - - char buffer[4][32]; - int j{0}; - for (const char *p : {"1 2 2*3 ,", ",6,,8,1*", - "2*'abcdefghijklmnopqrstuvwxyzABC", "DEFGHIJKLMNOPQRSTUVWXYZ'"}) { -SetCharacter(buffer[j++], sizeof buffer[0], p); - } - for (; j < 4; ++j) { -SetCharacter(buffer[j], sizeof buffer[0], ""); - } - - StaticDescriptor<1> staticDescriptor; - Descriptor &whole{staticDescriptor.descriptor()}; - SubscriptValue extent[]{4}; - whole.Establish(TypeCode{CFI_type_char}, sizeof buffer[0], &buffer, 1, extent, - CFI_attribute_pointer); - whole.Dump(); - whole.Check(); - - try { -auto cookie{IONAME(BeginInternalArrayListInput)(whole)}; -std::int64_t n[9]{-1, -2, -3, -4, 5, -6, 7, -8, 9}; -std::int64_t want[9]{1, 2, 3, 3, 5, 6, 7, 8, 9}; -for (j = 0; j < 9; ++j) { - IONAME(InputInteger)(cookie, n[j]); -} -char asc[2][54]{}; -IONAME(InputAscii)(cookie, asc[0], sizeof asc[0] - 1); -IONAME(InputAscii)(cookie, asc[1], sizeof asc[1] - 1); -if (auto status{IONAME(EndIoStatement)(cookie)}) { - Fail() << "list-directed input failed, status " - << static_cast(status) << '\n'; -} else { - for (j = 0; j < 9; ++j) { -if (n[j] != want[j]) { - Fail() << "wanted n[" << j << "]==" << want[j] << ", got " << n[j] - << '\n'; -} - } - for (j = 0; j < 2; ++j) { -if (std::strcmp(asc[j], -"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ") != 0) { - Fail() << "wanted asc[" << j << "]=alphabets, got '" << asc[j] - << "'\n"; -} - } -} - } catch (const std::string &crash) { -Fail() << "crash: " << crash << '\n'; - } - - return EndTests(); -} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] bc26c5f - Clang-format list input test
Author: Asher Mancinelli Date: 2021-03-30T11:31:39-07:00 New Revision: bc26c5fb2a5601971691a69c6d8bf9f7b5cd7326 URL: https://github.com/llvm/llvm-project/commit/bc26c5fb2a5601971691a69c6d8bf9f7b5cd7326 DIFF: https://github.com/llvm/llvm-project/commit/bc26c5fb2a5601971691a69c6d8bf9f7b5cd7326.diff LOG: Clang-format list input test Added: Modified: flang/unittests/RuntimeGTest/ListInputTest.cpp Removed: diff --git a/flang/unittests/RuntimeGTest/ListInputTest.cpp b/flang/unittests/RuntimeGTest/ListInputTest.cpp index f1f62197ae07e..5d693d77f2114 100644 --- a/flang/unittests/RuntimeGTest/ListInputTest.cpp +++ b/flang/unittests/RuntimeGTest/ListInputTest.cpp @@ -59,7 +59,7 @@ TEST(InputTest, TestListInput) { static const auto status{IONAME(EndIoStatement)(cookie)}; ASSERT_EQ(status, 0) << "list-directed input failed, status " - << static_cast(status) << '\n'; + << static_cast(status) << '\n'; for (j = 0; j < listInputLength; ++j) { ASSERT_EQ(n[j], want[j]) @@ -70,7 +70,7 @@ TEST(InputTest, TestListInput) { ASSERT_EQ(std::strcmp(inputBuffers[j], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "), 0) -<< "wanted asc[" << j << "]=alphabets, got '" << inputBuffers[j] << "'\n"; +<< "wanted asc[" << j << "]=alphabets, got '" << inputBuffers[j] +<< "'\n"; } } - ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] 679fe69 - Apply first pass at diag handler structure
Author: Asher Mancinelli Date: 2021-04-05T09:00:33-07:00 New Revision: 679fe69e92f192ef8d3b014dcf7e1624e16c9c77 URL: https://github.com/llvm/llvm-project/commit/679fe69e92f192ef8d3b014dcf7e1624e16c9c77 DIFF: https://github.com/llvm/llvm-project/commit/679fe69e92f192ef8d3b014dcf7e1624e16c9c77.diff LOG: Apply first pass at diag handler structure Added: flang/include/flang/Common/colors.h flang/include/flang/Parser/diagnostics-engine.h Modified: flang/include/flang/Parser/message.h flang/lib/Parser/message.cpp Removed: diff --git a/flang/include/flang/Common/colors.h b/flang/include/flang/Common/colors.h new file mode 100644 index 0..feb259c22c674 --- /dev/null +++ b/flang/include/flang/Common/colors.h @@ -0,0 +1,34 @@ +//===-- include/flang/Parser/colors.h ---*- C++ -*-===// +// +// 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 +// +//===--===// +// +// Defines colors used for diagnostics. +// +//===--===// + +#ifndef FORTRAN_PARSER_COLORS_H_ +#define FORTRAN_PARSER_COLORS_H_ + +#include "llvm/Support/raw_ostream.h" + +namespace Fortran::common { + +static constexpr enum llvm::raw_ostream::Colors noteColor = +llvm::raw_ostream::BLACK; +static constexpr enum llvm::raw_ostream::Colors remarkColor = +llvm::raw_ostream::BLUE; +static constexpr enum llvm::raw_ostream::Colors warningColor = +llvm::raw_ostream::MAGENTA; +static constexpr enum llvm::raw_ostream::Colors errorColor = llvm::raw_ostream::RED; +static constexpr enum llvm::raw_ostream::Colors fatalColor = llvm::raw_ostream::RED; +// Used for changing only the bold attribute. +static constexpr enum llvm::raw_ostream::Colors savedColor = +llvm::raw_ostream::SAVEDCOLOR; + +} // namespace Fortran::common + +#endif \ No newline at end of file diff --git a/flang/include/flang/Parser/diagnostics-engine.h b/flang/include/flang/Parser/diagnostics-engine.h new file mode 100644 index 0..beb03d77aeeb0 --- /dev/null +++ b/flang/include/flang/Parser/diagnostics-engine.h @@ -0,0 +1,20 @@ +//===-- include/flang/Parser/characters.h ---*- C++ -*-===// +// +// 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 +// +//===--===// + +#ifndef FORTRAN_PARSER_CHARACTERS_H_ +#define FORTRAN_PARSER_CHARACTERS_H_ + +namespace Fortran::parser { + +class DiagnosticsEngine { + +}; + +} // namespace Fortran::parser + +#endif \ No newline at end of file diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h index 13f30879dc4fb..fbba0b922e018 100644 --- a/flang/include/flang/Parser/message.h +++ b/flang/include/flang/Parser/message.h @@ -29,34 +29,46 @@ namespace Fortran::parser { +enum class DiagnosticLevel { + Note=0, + Remark, + Warning, + Error, + Fatal, +}; + // Use "..."_err_en_US and "..."_en_US literals to define the static // text and fatality of a message. class MessageFixedText { public: constexpr MessageFixedText( - const char str[], std::size_t n, bool isFatal = false) - : text_{str, n}, isFatal_{isFatal} {} + const char str[], std::size_t n, DiagnosticLevel diagnosticLevel = DiagnosticLevel::Remark) + : text_{str, n}, diagnosticLevel_{diagnosticLevel} {} + constexpr MessageFixedText( + const char str[], std::size_t n, bool isFatal) + : text_{str, n}, diagnosticLevel_{isFatal ? DiagnosticLevel::Fatal : DiagnosticLevel::Remark} {} constexpr MessageFixedText(const MessageFixedText &) = default; constexpr MessageFixedText(MessageFixedText &&) = default; constexpr MessageFixedText &operator=(const MessageFixedText &) = default; constexpr MessageFixedText &operator=(MessageFixedText &&) = default; CharBlock text() const { return text_; } - bool isFatal() const { return isFatal_; } + bool isFatal() const { return diagnosticLevel_ == DiagnosticLevel::Fatal; } + DiagnosticLevel GetDiagnosticLevel() const { return diagnosticLevel_; } private: CharBlock text_; - bool isFatal_{false}; + DiagnosticLevel diagnosticLevel_{DiagnosticLevel::Remark}; }; inline namespace literals { constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) { - return MessageFixedText{str, n, false /* not fatal */}; + return MessageFixedText{str, n, DiagnosticLevel::Remark}; } constexpr MessageFixedText operator""_err_en_US( const char str[], std::size_t n)
[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
@@ -0,0 +1,204 @@ +//===-- LLVMInsertChainFolder.cpp -===// +// +// 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 +// +//===--===// + +#include "flang/Optimizer/CodeGen/LLVMInsertChainFolder.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/Builders.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "flang-insert-folder" + +#include + +namespace { +// Helper class to construct the attribute elements of an aggregate value being +// folded without creating a full mlir::Attribute representation for each step +// of the insert value chain, which would both be expensive in terms of +// compilation time and memory (since the intermediate Attribute would survive, +// unused, inside the mlir context). +class InsertChainBackwardFolder { + // Type for the current value of an element of the aggregate value being + // constructed by the insert chain. + // At any point of the insert chain, the value of an element is either: + // - nullptr: not yet known, the insert has not yet been seen. + // - an mlir::Attribute: the element is fully defined. + // - a nested InsertChainBackwardFolder: the element is itself an aggregate + //and its sub-elements have been partially defined (insert with mutliple + //indices have been seen). + + // The insertion folder assumes backward walk of the insert chain. Once an + // element or sub-element has been defined, it is not overriden by new + // insertions (last insert wins). + using InFlightValue = + llvm::PointerUnion; + +public: + InsertChainBackwardFolder( + mlir::Type type, std::deque *folderStorage) + : values(getNumElements(type), mlir::Attribute{}), +folderStorage{folderStorage}, type{type} {} + + /// Push + bool pushValue(mlir::Attribute val, llvm::ArrayRef at); + + mlir::Attribute finalize(mlir::Attribute defaultFieldValue); + +private: + static int64_t getNumElements(mlir::Type type) { +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody().size(); +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getNumElements(); +return 0; + } + + static mlir::Type getSubElementType(mlir::Type type, int64_t field) { +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getElementType(); +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody()[field]; +return {}; + } + + // Current element value of the aggregate value being built. + llvm::SmallVector values; + // std::deque is used to allocate storage for nested list and guarantee the + // stability of the InsertChainBackwardFolder* used as element value. + std::deque *folderStorage; + // Type of the aggregate value being built. + mlir::Type type; +}; +} // namespace + +// Helper to fold the value being inserted by an llvm.insert_value. +// This may call tryFoldingLLVMInsertChain if the value is an aggregate and +// was itself constructed by a different insert chain. +static mlir::Attribute getAttrIfConstant(mlir::Value val, + mlir::OpBuilder &rewriter) { + if (auto cst = val.getDefiningOp()) +return cst.getValue(); + if (auto insert = val.getDefiningOp()) +return fir::tryFoldingLLVMInsertChain(val, rewriter); + if (val.getDefiningOp()) +return mlir::LLVM::ZeroAttr::get(val.getContext()); + if (val.getDefiningOp()) +return mlir::LLVM::UndefAttr::get(val.getContext()); + if (mlir::Operation *op = val.getDefiningOp()) { +unsigned resNum = llvm::cast(val).getResultNumber(); +llvm::SmallVector results; +if (mlir::succeeded(rewriter.tryFold(op, results)) && +results.size() > resNum) { + if (auto cst = results[resNum].getDefiningOp()) +return cst.getValue(); +} + } + if (auto trunc = val.getDefiningOp()) +if (auto attr = getAttrIfConstant(trunc.getArg(), rewriter)) + if (auto intAttr = llvm::dyn_cast(attr)) +return mlir::IntegerAttr::get(trunc.getType(), intAttr.getInt()); + LLVM_DEBUG(llvm::dbgs() << "cannot fold insert value operand: " << val + << "\n"); + return {}; +} + +mlir::Attribute +InsertChainBackwardFolder::finalize(mlir::Attribute defaultFieldValue) { + std::vector attrs; + attrs.reserve(values.size()); + for (InFlightValue &inFlight : values) { +if (!inFlight) { + attrs.push_back(defaultFieldValue); +} else if (auto attr = llvm::dyn_cast(inFlight)) { + attrs.push_back(attr); +} else { + auto *inFlightList = llvm::cast(inFlight); + attrs.push_back(inFlightList->finalize(defaul
[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
https://github.com/ashermancinelli edited https://github.com/llvm/llvm-project/pull/140268 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
@@ -0,0 +1,204 @@ +//===-- LLVMInsertChainFolder.cpp -===// +// +// 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 +// +//===--===// + +#include "flang/Optimizer/CodeGen/LLVMInsertChainFolder.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/Builders.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "flang-insert-folder" + +#include + +namespace { +// Helper class to construct the attribute elements of an aggregate value being +// folded without creating a full mlir::Attribute representation for each step +// of the insert value chain, which would both be expensive in terms of +// compilation time and memory (since the intermediate Attribute would survive, +// unused, inside the mlir context). +class InsertChainBackwardFolder { + // Type for the current value of an element of the aggregate value being + // constructed by the insert chain. + // At any point of the insert chain, the value of an element is either: + // - nullptr: not yet known, the insert has not yet been seen. + // - an mlir::Attribute: the element is fully defined. + // - a nested InsertChainBackwardFolder: the element is itself an aggregate + //and its sub-elements have been partially defined (insert with mutliple + //indices have been seen). + + // The insertion folder assumes backward walk of the insert chain. Once an + // element or sub-element has been defined, it is not overriden by new + // insertions (last insert wins). + using InFlightValue = + llvm::PointerUnion; + +public: + InsertChainBackwardFolder( + mlir::Type type, std::deque *folderStorage) + : values(getNumElements(type), mlir::Attribute{}), +folderStorage{folderStorage}, type{type} {} + + /// Push + bool pushValue(mlir::Attribute val, llvm::ArrayRef at); + + mlir::Attribute finalize(mlir::Attribute defaultFieldValue); + +private: + static int64_t getNumElements(mlir::Type type) { +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody().size(); +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getNumElements(); +return 0; + } + + static mlir::Type getSubElementType(mlir::Type type, int64_t field) { +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getElementType(); +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody()[field]; +return {}; + } + + // Current element value of the aggregate value being built. + llvm::SmallVector values; + // std::deque is used to allocate storage for nested list and guarantee the + // stability of the InsertChainBackwardFolder* used as element value. + std::deque *folderStorage; + // Type of the aggregate value being built. + mlir::Type type; +}; +} // namespace + +// Helper to fold the value being inserted by an llvm.insert_value. +// This may call tryFoldingLLVMInsertChain if the value is an aggregate and +// was itself constructed by a different insert chain. +static mlir::Attribute getAttrIfConstant(mlir::Value val, + mlir::OpBuilder &rewriter) { + if (auto cst = val.getDefiningOp()) +return cst.getValue(); + if (auto insert = val.getDefiningOp()) +return fir::tryFoldingLLVMInsertChain(val, rewriter); + if (val.getDefiningOp()) +return mlir::LLVM::ZeroAttr::get(val.getContext()); + if (val.getDefiningOp()) +return mlir::LLVM::UndefAttr::get(val.getContext()); + if (mlir::Operation *op = val.getDefiningOp()) { +unsigned resNum = llvm::cast(val).getResultNumber(); +llvm::SmallVector results; +if (mlir::succeeded(rewriter.tryFold(op, results)) && +results.size() > resNum) { + if (auto cst = results[resNum].getDefiningOp()) +return cst.getValue(); +} + } + if (auto trunc = val.getDefiningOp()) +if (auto attr = getAttrIfConstant(trunc.getArg(), rewriter)) + if (auto intAttr = llvm::dyn_cast(attr)) +return mlir::IntegerAttr::get(trunc.getType(), intAttr.getInt()); + LLVM_DEBUG(llvm::dbgs() << "cannot fold insert value operand: " << val + << "\n"); + return {}; +} + +mlir::Attribute +InsertChainBackwardFolder::finalize(mlir::Attribute defaultFieldValue) { + std::vector attrs; + attrs.reserve(values.size()); + for (InFlightValue &inFlight : values) { +if (!inFlight) { + attrs.push_back(defaultFieldValue); +} else if (auto attr = llvm::dyn_cast(inFlight)) { + attrs.push_back(attr); +} else { + auto *inFlightList = llvm::cast(inFlight); + attrs.push_back(inFlightList->finalize(defaul
[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
https://github.com/ashermancinelli approved this pull request. Thanks, this is a really interesting fix! My review comments are just nits/questions. https://github.com/llvm/llvm-project/pull/140268 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
@@ -0,0 +1,204 @@ +//===-- LLVMInsertChainFolder.cpp -===// +// +// 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 +// +//===--===// + +#include "flang/Optimizer/CodeGen/LLVMInsertChainFolder.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/Builders.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "flang-insert-folder" + +#include + +namespace { +// Helper class to construct the attribute elements of an aggregate value being +// folded without creating a full mlir::Attribute representation for each step +// of the insert value chain, which would both be expensive in terms of +// compilation time and memory (since the intermediate Attribute would survive, +// unused, inside the mlir context). +class InsertChainBackwardFolder { + // Type for the current value of an element of the aggregate value being + // constructed by the insert chain. + // At any point of the insert chain, the value of an element is either: + // - nullptr: not yet known, the insert has not yet been seen. + // - an mlir::Attribute: the element is fully defined. + // - a nested InsertChainBackwardFolder: the element is itself an aggregate + //and its sub-elements have been partially defined (insert with mutliple + //indices have been seen). + + // The insertion folder assumes backward walk of the insert chain. Once an + // element or sub-element has been defined, it is not overriden by new + // insertions (last insert wins). + using InFlightValue = + llvm::PointerUnion; + +public: + InsertChainBackwardFolder( + mlir::Type type, std::deque *folderStorage) + : values(getNumElements(type), mlir::Attribute{}), +folderStorage{folderStorage}, type{type} {} + + /// Push + bool pushValue(mlir::Attribute val, llvm::ArrayRef at); + + mlir::Attribute finalize(mlir::Attribute defaultFieldValue); + +private: + static int64_t getNumElements(mlir::Type type) { +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody().size(); +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getNumElements(); +return 0; + } + + static mlir::Type getSubElementType(mlir::Type type, int64_t field) { +if (auto arrayTy = +llvm::dyn_cast_if_present(type)) + return arrayTy.getElementType(); +if (auto structTy = +llvm::dyn_cast_if_present(type)) + return structTy.getBody()[field]; +return {}; + } ashermancinelli wrote: What does a default-constructed `mlir::Type` indicate here? https://github.com/llvm/llvm-project/pull/140268 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits