diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index e8005435e1836..b5965d163d7db 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -560,8 +560,8 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { dlog(" {0} #={1} *={2} Mode={3}", R.Text, R.ExactArgs, R.PrefixArgs, int(R.Modes)); } - dlog("Table spellings={0} rules={1} string-bytes={2}", Result->size(), - RuleCount, Result->getAllocator().getBytesAllocated()); + dlog("Table spellings={0} rules={1} allocator-bytes={2}", Result->size(), + RuleCount, Result->getAllocator().getTotalMemory()); #endif // The static table will never be destroyed. return Result.release(); diff --git a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp index f873774eb2019..ebdb0346b3bed 100644 --- a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp +++ b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp @@ -77,10 +77,13 @@ TEST_F(PPMemoryAllocationsTest, PPMacroDefinesAllocations) { PP.LexTokensUntilEOF(); - size_t NumAllocated = PP.getPreprocessorAllocator().getBytesAllocated(); - float BytesPerDefine = float(NumAllocated) / float(NumMacros); - llvm::errs() << "Num preprocessor allocations for " << NumMacros - << " #define: " << NumAllocated << "\n"; + // Use the total slab memory held by the preprocessor's allocator as a proxy. + // Over a million #defines the per-allocation slab overhead is negligible, so + // this closely tracks the bytes requested for storing the macro information. + size_t TotalMemory = PP.getPreprocessorAllocator().getTotalMemory(); + float BytesPerDefine = float(TotalMemory) / float(NumMacros); + llvm::errs() << "Preprocessor allocator memory for " << NumMacros + << " #define: " << TotalMemory << "\n"; llvm::errs() << "Bytes per #define: " << BytesPerDefine << "\n"; // On arm64-apple-macos, we get around 120 bytes per define. // Assume a reasonable upper bound based on that number that we don't want diff --git a/libc/shared/builtins.h b/libc/shared/builtins.h index dca0171c02d18..867bf6df0d306 100644 --- a/libc/shared/builtins.h +++ b/libc/shared/builtins.h @@ -21,6 +21,7 @@ #include "builtins/addtf3.h" #include "builtins/divtf3.h" #include "builtins/multf3.h" +#include "builtins/subdf3.h" #include "builtins/subtf3.h" #endif // LLVM_LIBC_SHARED_BUILTINS_H diff --git a/libc/shared/builtins/subdf3.h b/libc/shared/builtins/subdf3.h new file mode 100644 index 0000000000000..8cff7e3bfa28f --- /dev/null +++ b/libc/shared/builtins/subdf3.h @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This header exposes LLVM-libc's __subdf3 implementation as shared::subdf3 so +/// that it can be reused by compiler-rt's builtins. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_BUILTINS_SUBDF3_H +#define LLVM_LIBC_SHARED_BUILTINS_SUBDF3_H + +#include "shared/libc_common.h" +#include "src/__support/builtins/subdf3.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using builtins::subdf3; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_BUILTINS_SUBDF3_H diff --git a/libc/src/__support/builtins/CMakeLists.txt b/libc/src/__support/builtins/CMakeLists.txt index dee5a830b8857..47dbc6cddbf68 100644 --- a/libc/src/__support/builtins/CMakeLists.txt +++ b/libc/src/__support/builtins/CMakeLists.txt @@ -46,3 +46,12 @@ add_header_library( libc.src.__support.FPUtil.generic.add_sub libc.src.__support.macros.config ) + +add_header_library( + subdf3 + HDRS + subdf3.h + DEPENDS + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config +) diff --git a/libc/src/__support/builtins/subdf3.h b/libc/src/__support/builtins/subdf3.h new file mode 100644 index 0000000000000..5e704aa714af6 --- /dev/null +++ b/libc/src/__support/builtins/subdf3.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This header exposes LLVM-libc's __subdf3 implementation as builtins::subdf3 +/// so that it can be reused by compiler-rt's builtins. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_SUBDF3_H +#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_SUBDF3_H + +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace builtins { + +// Subtraction at double precision; mirrors compiler-rt's __subdf3. +LIBC_INLINE double subdf3(double x, double y) { + return fputil::generic::sub(x, y); +} + +} // namespace builtins +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_SUBDF3_H diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt index 120524bed5ead..a60b5bc537cc3 100644 --- a/libc/test/shared/CMakeLists.txt +++ b/libc/test/shared/CMakeLists.txt @@ -831,6 +831,7 @@ add_fp_unittest( libc.src.__support.builtins.addtf3 libc.src.__support.builtins.divtf3 libc.src.__support.builtins.multf3 + libc.src.__support.builtins.subdf3 libc.src.__support.builtins.subtf3 ) diff --git a/libc/test/shared/shared_builtins_test.cpp b/libc/test/shared/shared_builtins_test.cpp index 4960c7abe6b04..1de81ce129c20 100644 --- a/libc/test/shared/shared_builtins_test.cpp +++ b/libc/test/shared/shared_builtins_test.cpp @@ -16,6 +16,7 @@ TEST(LlvmLibcSharedBuiltinsTest, AllFloat) { TEST(LlvmLibcSharedBuiltinsTest, AllDouble) { EXPECT_FP_EQ(3.0, LIBC_NAMESPACE::shared::adddf3(1.0, 2.0)); + EXPECT_FP_EQ(2.0, LIBC_NAMESPACE::shared::subdf3(5.0, 3.0)); } #ifdef LIBC_TYPES_HAS_FLOAT128 diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h index 1bfefec9638a5..4452df1ecc6b1 100644 --- a/lldb/include/lldb/Utility/ConstString.h +++ b/lldb/include/lldb/Utility/ConstString.h @@ -393,10 +393,7 @@ class ConstString { struct MemoryStats { size_t GetBytesTotal() const { return bytes_total; } - size_t GetBytesUsed() const { return bytes_used; } - size_t GetBytesUnused() const { return bytes_total - bytes_used; } size_t bytes_total = 0; - size_t bytes_used = 0; }; static MemoryStats GetMemoryStats(); diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp index 9fee5108e736a..6227d099642f2 100644 --- a/lldb/source/Target/Statistics.cpp +++ b/lldb/source/Target/Statistics.cpp @@ -111,8 +111,6 @@ json::Value ModuleStats::ToJSON() const { llvm::json::Value ConstStringStats::ToJSON() const { json::Object obj; obj.try_emplace("bytesTotal", stats.GetBytesTotal()); - obj.try_emplace("bytesUsed", stats.GetBytesUsed()); - obj.try_emplace("bytesUnused", stats.GetBytesUnused()); return obj; } diff --git a/lldb/source/Utility/ConstString.cpp b/lldb/source/Utility/ConstString.cpp index 3d79731a47d5a..8def38c03dceb 100644 --- a/lldb/source/Utility/ConstString.cpp +++ b/lldb/source/Utility/ConstString.cpp @@ -196,7 +196,6 @@ class Pool { std::shared_lock lock(pool.m_mutex); const Allocator &alloc = pool.m_string_map.getAllocator(); stats.bytes_total += alloc.getTotalMemory(); - stats.bytes_used += alloc.getBytesAllocated(); } return stats; } diff --git a/lldb/test/API/commands/statistics/basic/TestStats.py b/lldb/test/API/commands/statistics/basic/TestStats.py index a32b8feecc5cf..c65d1d8785160 100644 --- a/lldb/test/API/commands/statistics/basic/TestStats.py +++ b/lldb/test/API/commands/statistics/basic/TestStats.py @@ -348,8 +348,6 @@ def test_memory(self): strings = memory["strings"] strings_keys = [ "bytesTotal", - "bytesUsed", - "bytesUnused", ] self.verify_keys(strings, '"strings"', strings_keys, None) diff --git a/llvm/include/llvm/Support/Allocator.h b/llvm/include/llvm/Support/Allocator.h index ea8e8a829ee55..bb0ca118e2015 100644 --- a/llvm/include/llvm/Support/Allocator.h +++ b/llvm/include/llvm/Support/Allocator.h @@ -18,6 +18,7 @@ #define LLVM_SUPPORT_ALLOCATOR_H #include "llvm/ADT/SmallVector.h" +#include "llvm/Config/abi-breaking.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/AllocatorBase.h" #include "llvm/Support/Compiler.h" @@ -36,9 +37,7 @@ namespace detail { // We call out to an external function to actually print the message as the // printing code uses Allocator.h in its implementation. -LLVM_ABI void printBumpPtrAllocatorStats(unsigned NumSlabs, - size_t BytesAllocated, - size_t TotalMemory); +LLVM_ABI void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t TotalMemory); } // end namespace detail @@ -96,11 +95,12 @@ class BumpPtrAllocatorImpl BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old) : AllocTy(std::move(Old.getAllocator())), CurPtr(Old.CurPtr), EndSentinel(Old.EndSentinel), Slabs(std::move(Old.Slabs)), - CustomSizedSlabs(std::move(Old.CustomSizedSlabs)), - BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize) { + CustomSizedSlabs(std::move(Old.CustomSizedSlabs)) { +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + RedZoneSize = Old.RedZoneSize; +#endif Old.CurPtr = nullptr; Old.EndSentinel = 0; - Old.BytesAllocated = 0; Old.Slabs.clear(); Old.CustomSizedSlabs.clear(); } @@ -116,15 +116,15 @@ class BumpPtrAllocatorImpl CurPtr = RHS.CurPtr; EndSentinel = RHS.EndSentinel; - BytesAllocated = RHS.BytesAllocated; +#if LLVM_ENABLE_ABI_BREAKING_CHECKS RedZoneSize = RHS.RedZoneSize; +#endif Slabs = std::move(RHS.Slabs); CustomSizedSlabs = std::move(RHS.CustomSizedSlabs); AllocTy::operator=(std::move(RHS.getAllocator())); RHS.CurPtr = nullptr; RHS.EndSentinel = 0; - RHS.BytesAllocated = 0; RHS.Slabs.clear(); RHS.CustomSizedSlabs.clear(); return *this; @@ -141,7 +141,6 @@ class BumpPtrAllocatorImpl return; // Reset the state. - BytesAllocated = 0; CurPtr = (char *)Slabs.front(); EndSentinel = uintptr_t(CurPtr) + SlabSize + 1; @@ -158,12 +157,10 @@ class BumpPtrAllocatorImpl // Allocate(0, N) is valid, it returns a non-null pointer (which should not // be dereferenced). LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, Align Alignment) { - // Keep track of how many bytes we've allocated. - BytesAllocated += Size; - size_t SizeToAllocate = Size; -#if LLVM_ADDRESS_SANITIZER_BUILD - // Add trailing bytes as a "red zone" under ASan. +#if LLVM_ADDRESS_SANITIZER_BUILD && LLVM_ENABLE_ABI_BREAKING_CHECKS + // Add trailing bytes as a "red zone" under ASan. RedZoneSize only exists + // when both conditions are true. SizeToAllocate += RedZoneSize; #endif SizeToAllocate = alignToPowerOf2(SizeToAllocate, MinAlign); @@ -308,15 +305,14 @@ class BumpPtrAllocatorImpl return TotalMemory; } - size_t getBytesAllocated() const { return BytesAllocated; } - - void setRedZoneSize(size_t NewSize) { + void setRedZoneSize([[maybe_unused]] size_t NewSize) { +#if LLVM_ENABLE_ABI_BREAKING_CHECKS RedZoneSize = NewSize; +#endif } void PrintStats() const { - detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated, - getTotalMemory()); + detail::printBumpPtrAllocatorStats(Slabs.size(), getTotalMemory()); } private: @@ -335,14 +331,11 @@ class BumpPtrAllocatorImpl /// Custom-sized slabs allocated for too-large allocation requests. SmallVector, 0> CustomSizedSlabs; - /// How many bytes we've allocated. - /// - /// Used so that we can compute how much space was wasted. - size_t BytesAllocated = 0; - - /// The number of bytes to put between allocations when running under - /// a sanitizer. +#if LLVM_ENABLE_ABI_BREAKING_CHECKS + /// The number of bytes to put between allocations when running under a + /// sanitizer. size_t RedZoneSize = 1; +#endif static size_t computeSlabSize(unsigned SlabIdx) { // Scale the actual allocated slab size based on the number of slabs @@ -472,8 +465,6 @@ template class SpecificBumpPtrAllocator { std::optional identifyObject(const void *Ptr) { return Allocator.identifyObject(Ptr); } - - size_t getBytesAllocated() const { return Allocator.getBytesAllocated(); } }; } // end namespace llvm diff --git a/llvm/include/llvm/Support/PerThreadBumpPtrAllocator.h b/llvm/include/llvm/Support/PerThreadBumpPtrAllocator.h index f94d18f62e9ab..0448fb2a12a9b 100644 --- a/llvm/include/llvm/Support/PerThreadBumpPtrAllocator.h +++ b/llvm/include/llvm/Support/PerThreadBumpPtrAllocator.h @@ -82,16 +82,6 @@ class PerThreadAllocator return TotalMemory; } - /// Return allocated size by all allocators. - size_t getBytesAllocated() const { - size_t BytesAllocated = 0; - - for (size_t Idx = 0; Idx < getNumberOfAllocators(); Idx++) - BytesAllocated += Allocators[Idx].getBytesAllocated(); - - return BytesAllocated; - } - /// Set red zone for all allocators. void setRedZoneSize(size_t NewSize) { for (size_t Idx = 0; Idx < getNumberOfAllocators(); Idx++) diff --git a/llvm/include/llvm/Support/WithColor.h b/llvm/include/llvm/Support/WithColor.h index 2835e179e6195..febf211c3a391 100644 --- a/llvm/include/llvm/Support/WithColor.h +++ b/llvm/include/llvm/Support/WithColor.h @@ -68,6 +68,8 @@ class WithColor { /// @param Bold Bold/brighter text, default false /// @param BG If true, change the background, default: change foreground /// @param Mode Enable, disable or compute whether to use colors. + /// + /// FIXME: If Color == SAVEDCOLOR, Bold == false is currently ignored. LLVM_CTOR_NODISCARD WithColor( raw_ostream &OS, raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR, bool Bold = false, bool BG = false, ColorMode Mode = ColorMode::Auto) @@ -117,6 +119,8 @@ class WithColor { /// change only the bold attribute, and keep colors untouched /// @param Bold Bold/brighter text, default false /// @param BG If true, change the background, default: change foreground + /// + /// FIXME: If Color == SAVEDCOLOR, Bold == false is currently ignored. LLVM_ABI WithColor &changeColor(raw_ostream::Colors Color, bool Bold = false, bool BG = false); diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index 70916d8e4adb0..1e66052c849b7 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -332,6 +332,8 @@ class LLVM_ABI raw_ostream { /// @param Bold bold/brighter text, default false /// @param BG if true change the background, default: change foreground /// @returns itself so it can be used within << invocations + /// + /// FIXME: If Color == SAVEDCOLOR, Bold == false is currently ignored. virtual raw_ostream &changeColor(enum Colors Color, bool Bold = false, bool BG = false); diff --git a/llvm/lib/Support/Allocator.cpp b/llvm/lib/Support/Allocator.cpp index 1af5744bf301e..6ff68f1be3d63 100644 --- a/llvm/lib/Support/Allocator.cpp +++ b/llvm/lib/Support/Allocator.cpp @@ -17,12 +17,9 @@ namespace llvm { namespace detail { -void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated, - size_t TotalMemory) { +void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t TotalMemory) { errs() << "\nNumber of memory regions: " << NumSlabs << '\n' - << "Bytes used: " << BytesAllocated << '\n' << "Bytes allocated: " << TotalMemory << '\n' - << "Bytes wasted: " << (TotalMemory - BytesAllocated) << " (includes alignment, etc)\n"; } diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index e21588101dc37..e9d7febf12272 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -120,7 +120,6 @@ void detail::RecordKeeperImpl::dumpAllocationStats(raw_ostream &OS) const { OS << "TheVarBitInitPool size = " << TheVarBitInitPool.size() << '\n'; OS << "TheVarDefInitPool size = " << TheVarDefInitPool.size() << '\n'; OS << "TheFieldInitPool size = " << TheFieldInitPool.size() << '\n'; - OS << "Bytes allocated = " << Allocator.getBytesAllocated() << '\n'; OS << "Total allocator memory = " << Allocator.getTotalMemory() << "\n\n"; OS << "Number of records instantiated = " << LastRecordID << '\n'; diff --git a/llvm/test/FileCheck/dump-input/color.txt b/llvm/test/FileCheck/dump-input/color.txt new file mode 100644 index 0000000000000..9d343c0e0fb08 --- /dev/null +++ b/llvm/test/FileCheck/dump-input/color.txt @@ -0,0 +1,112 @@ +; Check that, when color is enabled, input dumps are colored as desired. Other +; tests check when colors are enabled generally. +; +; There are many redundant ANSI escape sequences in FileCheck's color output. +; In particular, all sequences immediately preceding a with no text in +; between are redundant. These sequences should have no impact on what the +; FileCheck user sees. + +; REQUIRES: ansi-escapes + +; RUN: split-file %s %t + +; DEFINE: %{opts} = +; DEFINE: %{run} = \ +; DEFINE: %ProtectFileCheckOutput \ +; DEFINE: not FileCheck -color -dump-input=always -dump-input-filter=error \ +; DEFINE: -dump-input-context=2 %{opts} %t/check.txt < %t/input.txt \ +; DEFINE: 2>&1 | \ +; DEFINE: %{reveal-ansi-escapes} | \ +; DEFINE: FileCheck %s -match-full-lines -check-prefixes + +; REDEFINE: %{opts} = +; RUN: %{run} CHECK-Q +; REDEFINE: %{opts} = -v +; RUN: %{run} CHECK-V +; REDEFINE: %{opts} = -vv +; RUN: %{run} CHECK-VV + +; Without -v or -vv: +; - Line numbers and ellipses are bright black. +; - Input text is reset to the default. +; - Errors are red. +; - Fuzzy matches are magenta. +; +; CHECK-Q: Input was: +; CHECK-Q-NEXT: <<<<<< +; CHECK-Q-NEXT: 1: hello +; CHECK-Q-NEXT: dag:2'0 { search range start (exclusive) +; CHECK-Q-NEXT: dag:2'1 error: no match found in search range +; CHECK-Q-NEXT: 2: jello +; CHECK-Q-NEXT: dag:2'2 ? possible intended match +; CHECK-Q-NEXT: 3: end +; CHECK-Q-NEXT: dag:2'3 } search range end (exclusive) +; CHECK-Q-NEXT: 4: foo +; CHECK-Q-NEXT: 5: foo +; CHECK-Q-NEXT: . +; CHECK-Q-NEXT: . +; CHECK-Q-NEXT: . +; CHECK-Q-NEXT: >>>>>> + +; With -v, all of the above is true but: +; - Successes are green. +; - Unmatched input text now has a cyan background. +; +; CHECK-V: Input was: +; CHECK-V-NEXT: <<<<<< +; CHECK-V-NEXT: 1: hello +; CHECK-V-NEXT: dag:1 ^~~~~ +; CHECK-V-NEXT: dag:2'0 { search range start (exclusive) +; CHECK-V-NEXT: dag:2'1 error: no match found in search range +; CHECK-V-NEXT: 2: jello +; CHECK-V-NEXT: dag:2'2 ? possible intended match +; CHECK-V-NEXT: 3: end +; CHECK-V-NEXT: label:3 ^~~ +; CHECK-V-NEXT: dag:2'3 } search range end (exclusive) +; CHECK-V-NEXT: 4: foo +; CHECK-V-NEXT: 5: foo +; CHECK-V-NEXT: . +; CHECK-V-NEXT: . +; CHECK-V-NEXT: . +; CHECK-V-NEXT: >>>>>> + +; With -vv, all of the above is true but: +; - Discarded matches are cyan. +; +; CHECK-VV: Input was: +; CHECK-VV-NEXT: <<<<<< +; CHECK-VV-NEXT: 1: hello +; CHECK-VV-NEXT: dag:1 ^~~~~ +; CHECK-VV-NEXT: dag:2'0 !~~~~ discard: overlaps earlier match +; CHECK-VV-NEXT: dag:2'1 { search range start (exclusive) +; CHECK-VV-NEXT: dag:2'2 error: no match found in search range +; CHECK-VV-NEXT: 2: jello +; CHECK-VV-NEXT: dag:2'3 ? possible intended match +; CHECK-VV-NEXT: 3: end +; CHECK-VV-NEXT: label:3 ^~~ +; CHECK-VV-NEXT: dag:2'4 } search range end (exclusive) +; CHECK-VV-NEXT: 4: foo +; CHECK-VV-NEXT: 5: foo +; CHECK-VV-NEXT: . +; CHECK-VV-NEXT: . +; CHECK-VV-NEXT: . +; CHECK-VV-NEXT: >>>>>> + +;--- check.txt +CHECK-DAG: hello +CHECK-DAG: hello +CHECK-LABEL: end + +;--- input.txt +hello +jello +end +foo +foo +foo +foo +foo +foo +foo +foo +foo diff --git a/llvm/test/FileCheck/opt-color.txt b/llvm/test/FileCheck/opt-color.txt index b12fa768881fe..87be3f899f967 100644 --- a/llvm/test/FileCheck/opt-color.txt +++ b/llvm/test/FileCheck/opt-color.txt @@ -1,22 +1,30 @@ +; Check when color is enabled. + +; REQUIRES: ansi-escapes + ; Create a case that produces a simple diagnostic. ; RUN: echo foo > %t.in ; CHECK: bar ; Run without and with -color. In the former case, FileCheck should suppress ; color in its diagnostics because stderr is a file. -; RUN: %ProtectFileCheckOutput not FileCheck %s < %t.in 2> %t.no-color -; RUN: %ProtectFileCheckOutput not FileCheck -color %s < %t.in 2> %t.color +; RUN: %ProtectFileCheckOutput not FileCheck %s < %t.in 2>&1 | \ +; RUN: %{reveal-ansi-escapes} > %t.no-color +; RUN: %ProtectFileCheckOutput not FileCheck -color %s < %t.in 2>&1 | \ +; RUN: %{reveal-ansi-escapes} > %t.color ; Check whether color was produced. -; RUN: FileCheck -check-prefix NO-COLOR %s < %t.no-color -; RUN: FileCheck -check-prefix COLOR %s < %t.color +; DEFINE: %{no-color} = FileCheck -check-prefix=NO-COLOR %s +; DEFINE: %{color} = FileCheck -check-prefix=COLOR %s +; RUN: %{no-color} < %t.no-color +; RUN: %{color} < %t.color ; Make sure our NO-COLOR and COLOR patterns are sane: they don't match the ; opposite cases. -; RUN: not FileCheck -check-prefix COLOR %s < %t.no-color -; RUN: not FileCheck -check-prefix NO-COLOR %s < %t.color +; RUN: not %{no-color} < %t.color +; RUN: not %{color} < %t.no-color -; I don't know of a good way to check for ANSI color codes, so just make sure -; some new characters show up where those codes should appear. +; The goal here is not to check the exact details of how colors are used. We +; just check whether colors are enabled at all. ; NO-COLOR: : error: CHECK: expected string not found in input -; COLOR: : {{.+}}error: {{.+}}CHECK: expected string not found in input +; COLOR: error: diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 09df1e3fd6281..cd028963dd59e 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -853,6 +853,99 @@ def host_unwind_supports_jit(): if config.has_logf128: config.available_features.add("has_logf128") +# ANSI escape sequences. +# +# For example: +# +# REQUIRES: ansi-escapes +# RUN: some-cmd -color 2>&1 | %{reveal-ansi-escapes} | FileCheck %s +# CHECK: Once in a blue moon, I'm green with envy. +if platform.system() not in ["Windows"]: + config.available_features.add("ansi-escapes") + # It is not clear that the escape sequence \x1b is portable across sed + # implementations, but that is ok because python substitutes the raw + # character here. + config.substitutions.append( + ( + "%{reveal-ansi-escapes}", + "sed " + # Foreground colors. + "-e 's/\x1b\\[0;30m//g' " + "-e 's/\x1b\\[0;31m//g' " + "-e 's/\x1b\\[0;32m//g' " + "-e 's/\x1b\\[0;33m//g' " + "-e 's/\x1b\\[0;34m//g' " + "-e 's/\x1b\\[0;35m//g' " + "-e 's/\x1b\\[0;36m//g' " + "-e 's/\x1b\\[0;37m//g' " + "-e 's/\x1b\\[0;90m//g' " + "-e 's/\x1b\\[0;91m//g' " + "-e 's/\x1b\\[0;92m//g' " + "-e 's/\x1b\\[0;93m//g' " + "-e 's/\x1b\\[0;94m//g' " + "-e 's/\x1b\\[0;95m//g' " + "-e 's/\x1b\\[0;96m//g' " + "-e 's/\x1b\\[0;97m//g' " + # Bold foreground colors. + "-e 's/\x1b\\[0;1;30m//g' " + "-e 's/\x1b\\[0;1;31m//g' " + "-e 's/\x1b\\[0;1;32m//g' " + "-e 's/\x1b\\[0;1;33m//g' " + "-e 's/\x1b\\[0;1;34m//g' " + "-e 's/\x1b\\[0;1;35m//g' " + "-e 's/\x1b\\[0;1;36m//g' " + "-e 's/\x1b\\[0;1;37m//g' " + "-e 's/\x1b\\[0;1;90m//g' " + "-e 's/\x1b\\[0;1;91m//g' " + "-e 's/\x1b\\[0;1;92m//g' " + "-e 's/\x1b\\[0;1;93m//g' " + "-e 's/\x1b\\[0;1;94m//g' " + "-e 's/\x1b\\[0;1;95m//g' " + "-e 's/\x1b\\[0;1;96m//g' " + "-e 's/\x1b\\[0;1;97m//g' " + # Background colors. + "-e 's/\x1b\\[0;40m//g' " + "-e 's/\x1b\\[0;41m//g' " + "-e 's/\x1b\\[0;42m//g' " + "-e 's/\x1b\\[0;43m//g' " + "-e 's/\x1b\\[0;44m//g' " + "-e 's/\x1b\\[0;45m//g' " + "-e 's/\x1b\\[0;46m//g' " + "-e 's/\x1b\\[0;47m//g' " + "-e 's/\x1b\\[0;100m//g' " + "-e 's/\x1b\\[0;101m//g' " + "-e 's/\x1b\\[0;102m//g' " + "-e 's/\x1b\\[0;103m//g' " + "-e 's/\x1b\\[0;104m//g' " + "-e 's/\x1b\\[0;105m//g' " + "-e 's/\x1b\\[0;106m//g' " + "-e 's/\x1b\\[0;107m//g' " + # Bold background colors. + "-e 's/\x1b\\[0;1;40m//g' " + "-e 's/\x1b\\[0;1;41m//g' " + "-e 's/\x1b\\[0;1;42m//g' " + "-e 's/\x1b\\[0;1;43m//g' " + "-e 's/\x1b\\[0;1;44m//g' " + "-e 's/\x1b\\[0;1;45m//g' " + "-e 's/\x1b\\[0;1;46m//g' " + "-e 's/\x1b\\[0;1;47m//g' " + "-e 's/\x1b\\[0;1;100m//g' " + "-e 's/\x1b\\[0;1;101m//g' " + "-e 's/\x1b\\[0;1;102m//g' " + "-e 's/\x1b\\[0;1;103m//g' " + "-e 's/\x1b\\[0;1;104m//g' " + "-e 's/\x1b\\[0;1;105m//g' " + "-e 's/\x1b\\[0;1;106m//g' " + "-e 's/\x1b\\[0;1;107m//g' " + # Misc. + "-e 's/\x1b\\[1m//g' " + "-e 's/\x1b\\[7m//g' " + "-e 's/\x1b\\[0m//g' " + # Reveal any sequence we missed above. + "-e 's/\x1b//g' ", + ) + ) + if lit_config.update_tests: import sys import os diff --git a/llvm/test/tools/obj2yaml/DXContainer/PRIVPart.yaml b/llvm/test/tools/obj2yaml/DXContainer/PRIVPart.yaml index 0d429a1381413..b7324c28e930d 100644 --- a/llvm/test/tools/obj2yaml/DXContainer/PRIVPart.yaml +++ b/llvm/test/tools/obj2yaml/DXContainer/PRIVPart.yaml @@ -2,7 +2,9 @@ ## part size is not a multiple of 4. The pipeline is run twice to ensure obj2yaml ## output with a non-multiple-of-4 FileSize can be fed back through yaml2obj. -# RUN: yaml2obj %s 2>&1 | obj2yaml 2>&1 | yaml2obj %s 2>&1 | obj2yaml 2>&1 | FileCheck %s +# RUN: yaml2obj %s -o %t.dxbc +# RUN: obj2yaml %t.dxbc | yaml2obj -o %t2.dxbc +# RUN: obj2yaml %t2.dxbc | FileCheck %s --- !dxcontainer Header: diff --git a/llvm/tools/llubi/lib/Context.cpp b/llvm/tools/llubi/lib/Context.cpp index bd7c966a1c7e9..e89f7a43b45c6 100644 --- a/llvm/tools/llubi/lib/Context.cpp +++ b/llvm/tools/llubi/lib/Context.cpp @@ -368,9 +368,8 @@ const MaterializedConstant *Context::getConstantValue(Constant *C) { if (Val.isNone()) return nullptr; if (!Val.isCacheable()) { - assert(NoncacheableConstBuffer.getBytesAllocated() <= - 1024 * sizeof(MaterializedConstant) && - "Unbounded temporary buffer."); + assert(NoncacheableConstCount <= 1024 && "Unbounded temporary buffer."); + ++NoncacheableConstCount; return new (NoncacheableConstBuffer.Allocate()) MaterializedConstant(std::move(Val)); } @@ -380,6 +379,7 @@ const MaterializedConstant *Context::getConstantValue(Constant *C) { void Context::resetNoncacheableConstantBuffer() { NoncacheableConstBuffer.DestroyAll(); + NoncacheableConstCount = 0; } APInt Context::getTag(uint32_t BitWidth, Provenance &Prov) { diff --git a/llvm/tools/llubi/lib/Context.h b/llvm/tools/llubi/lib/Context.h index d8e3450c4accd..097f0d1e0ab8b 100644 --- a/llvm/tools/llubi/lib/Context.h +++ b/llvm/tools/llubi/lib/Context.h @@ -306,6 +306,7 @@ class Context { // Temporary buffer for non-cacheable constants (e.g., // undef/ptrtoint/inttoptr). SpecificBumpPtrAllocator NoncacheableConstBuffer; + size_t NoncacheableConstCount = 0; DenseMap FuncAddrMap; DenseMap BlockAddrMap; DenseMap>> diff --git a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp index 05c480959142b..446b41795143e 100644 --- a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp +++ b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp @@ -49,7 +49,6 @@ TEST(ConcurrentHashTableTest, AddStringEntries) { parallel::TaskGroup tg; tg.spawn([&]() { - size_t AllocatedBytesAtStart = Allocator.getBytesAllocated(); std::pair res1 = HashTable.insert("1"); // Check entry is inserted. EXPECT_TRUE(res1.first->getKey() == "1"); @@ -79,8 +78,6 @@ TEST(ConcurrentHashTableTest, AddStringEntries) { // Check first entry is still valid. EXPECT_TRUE(res1.first->getKey() == "1"); - // Check data was allocated by allocator. - EXPECT_TRUE(Allocator.getBytesAllocated() > AllocatedBytesAtStart); // Check statistic. std::string StatisticString; @@ -107,15 +104,10 @@ TEST(ConcurrentHashTableTest, AddStringMultiplueEntries) { tg.spawn([&]() { // Check insertion. for (size_t I = 0; I < NumElements; I++) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() > - AllocatedBytesAtStart); } std::string StatisticString; @@ -129,16 +121,10 @@ TEST(ConcurrentHashTableTest, AddStringMultiplueEntries) { // Check insertion of duplicates. for (size_t I = 0; I < NumElements; I++) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - // Check no additional bytes were allocated for duplicate. - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() == - AllocatedBytesAtStart); } // Check statistic. @@ -165,15 +151,10 @@ TEST(ConcurrentHashTableTest, AddStringMultiplueEntriesWithResize) { tg.spawn([&]() { // Check insertion. for (size_t I = 0; I < NumElements; I++) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0} {1}", I, I + 100); std::pair Entry = HashTable.insert(StringForElement); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() > - AllocatedBytesAtStart); } std::string StatisticString; @@ -187,16 +168,10 @@ TEST(ConcurrentHashTableTest, AddStringMultiplueEntriesWithResize) { // Check insertion of duplicates. for (size_t I = 0; I < NumElements; I++) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0} {1}", I, I + 100); std::pair Entry = HashTable.insert(StringForElement); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - // Check no additional bytes were allocated for duplicate. - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() == - AllocatedBytesAtStart); } // Check statistic. @@ -217,15 +192,10 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallel) { // Check parallel insertion. parallelFor(0, NumElements, [&](size_t I) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() > - AllocatedBytesAtStart); }); std::string StatisticString; @@ -239,16 +209,10 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallel) { // Check parallel insertion of duplicates. parallelFor(0, NumElements, [&](size_t I) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - // Check no additional bytes were allocated for duplicate. - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() == - AllocatedBytesAtStart); }); // Check statistic. @@ -268,15 +232,10 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallelWithResize) { // Check parallel insertion. parallelFor(0, NumElements, [&](size_t I) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_TRUE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() > - AllocatedBytesAtStart); }); std::string StatisticString; @@ -290,16 +249,10 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallelWithResize) { // Check parallel insertion of duplicates. parallelFor(0, NumElements, [&](size_t I) { - BumpPtrAllocator &ThreadLocalAllocator = - Allocator.getThreadLocalAllocator(); - size_t AllocatedBytesAtStart = ThreadLocalAllocator.getBytesAllocated(); std::string StringForElement = formatv("{0}", I); std::pair Entry = HashTable.insert(StringForElement); EXPECT_FALSE(Entry.second); EXPECT_TRUE(Entry.first->getKey() == StringForElement); - // Check no additional bytes were allocated for duplicate. - EXPECT_TRUE(ThreadLocalAllocator.getBytesAllocated() == - AllocatedBytesAtStart); }); // Check statistic. diff --git a/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp b/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp index d1f04e9b28a34..86be4ee0f2aab 100644 --- a/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp +++ b/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp @@ -110,7 +110,6 @@ TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) { StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA"; EXPECT_THAT_ERROR(R.readFixedString(Str, 1), Succeeded()); EXPECT_EQ(Str, StringRef("A")); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Tests that a read which crosses a block boundary, but where the subsequent @@ -124,12 +123,10 @@ TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) { StringRef Str; EXPECT_THAT_ERROR(R.readFixedString(Str, 2), Succeeded()); EXPECT_EQ(Str, StringRef("AB")); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); R.setOffset(6); EXPECT_THAT_ERROR(R.readFixedString(Str, 4), Succeeded()); EXPECT_EQ(Str, StringRef("GHIJ")); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Tests that a read which crosses a block boundary and cannot be referenced @@ -143,7 +140,6 @@ TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) { StringRef Str; EXPECT_THAT_ERROR(R.readFixedString(Str, 10), Succeeded()); EXPECT_EQ(Str, StringRef("ABCDEFGHIJ")); - EXPECT_EQ(10U, F.Allocator.getBytesAllocated()); } // Test that an out of bounds read which doesn't cross a block boundary @@ -157,7 +153,6 @@ TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) { R.setOffset(10); EXPECT_THAT_ERROR(R.readFixedString(Str, 1), Failed()); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Test that an out of bounds read which crosses a contiguous block boundary @@ -171,7 +166,6 @@ TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) { R.setOffset(6); EXPECT_THAT_ERROR(R.readFixedString(Str, 5), Failed()); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Test that an out of bounds read which crosses a discontiguous block @@ -184,7 +178,6 @@ TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) { StringRef Str; EXPECT_THAT_ERROR(R.readFixedString(Str, 11), Failed()); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Tests that a read which is entirely contained within a single block but @@ -197,7 +190,6 @@ TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) { StringRef Str; EXPECT_THAT_ERROR(R.readFixedString(Str, 1), Succeeded()); EXPECT_EQ(Str, StringRef("A")); - EXPECT_EQ(0U, F.Allocator.getBytesAllocated()); } // Tests that a read which is not aligned on the same boundary as a previous @@ -212,13 +204,11 @@ TEST(MappedBlockStreamTest, UnalignedOverlappingRead) { StringRef Str2; EXPECT_THAT_ERROR(R.readFixedString(Str1, 7), Succeeded()); EXPECT_EQ(Str1, StringRef("ABCDEFG")); - EXPECT_EQ(7U, F.Allocator.getBytesAllocated()); R.setOffset(2); EXPECT_THAT_ERROR(R.readFixedString(Str2, 3), Succeeded()); EXPECT_EQ(Str2, StringRef("CDE")); EXPECT_EQ(Str1.data() + 2, Str2.data()); - EXPECT_EQ(7U, F.Allocator.getBytesAllocated()); } // Tests that a read which is not aligned on the same boundary as a previous @@ -233,12 +223,10 @@ TEST(MappedBlockStreamTest, UnalignedOverlappingReadFail) { StringRef Str2; EXPECT_THAT_ERROR(R.readFixedString(Str1, 6), Succeeded()); EXPECT_EQ(Str1, StringRef("ABCDEF")); - EXPECT_EQ(6U, F.Allocator.getBytesAllocated()); R.setOffset(4); EXPECT_THAT_ERROR(R.readFixedString(Str2, 4), Succeeded()); EXPECT_EQ(Str2, StringRef("EFGH")); - EXPECT_EQ(10U, F.Allocator.getBytesAllocated()); } TEST(MappedBlockStreamTest, WriteBeyondEndOfStream) { diff --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp index d6f80e0948dc4..744967de9004e 100644 --- a/llvm/unittests/Support/AllocatorTest.cpp +++ b/llvm/unittests/Support/AllocatorTest.cpp @@ -105,24 +105,20 @@ TEST(AllocatorTest, TestAlignment) { // we end up creating a slab for it. TEST(AllocatorTest, TestZero) { BumpPtrAllocator Alloc; - Alloc.setRedZoneSize(0); // else our arithmetic is all off + Alloc.setRedZoneSize(0); // else the slab count below is off under ASan EXPECT_EQ(0u, Alloc.GetNumSlabs()); - EXPECT_EQ(0u, Alloc.getBytesAllocated()); void *Empty = Alloc.Allocate(0, 1); EXPECT_NE(Empty, nullptr) << "Allocate is __attribute__((returns_nonnull))"; EXPECT_EQ(1u, Alloc.GetNumSlabs()) << "Allocated a slab to point to"; - EXPECT_EQ(0u, Alloc.getBytesAllocated()); void *Large = Alloc.Allocate(4096, 1); EXPECT_EQ(1u, Alloc.GetNumSlabs()); - EXPECT_EQ(4096u, Alloc.getBytesAllocated()); EXPECT_EQ(Empty, Large); void *Empty2 = Alloc.Allocate(0, 1); EXPECT_NE(Empty2, nullptr); EXPECT_EQ(1u, Alloc.GetNumSlabs()); - EXPECT_EQ(4096u, Alloc.getBytesAllocated()); } // Test allocating just over the slab size. This tests a bug where before the diff --git a/llvm/unittests/Support/PerThreadBumpPtrAllocatorTest.cpp b/llvm/unittests/Support/PerThreadBumpPtrAllocatorTest.cpp index d30de997f0fd1..4ac5ac4e1ff3b 100644 --- a/llvm/unittests/Support/PerThreadBumpPtrAllocatorTest.cpp +++ b/llvm/unittests/Support/PerThreadBumpPtrAllocatorTest.cpp @@ -26,13 +26,11 @@ TEST(PerThreadBumpPtrAllocatorTest, Simple) { (uint64_t *)Allocator.Allocate(sizeof(uint64_t), alignof(uint64_t)); *Var = 0xFE; EXPECT_EQ(0xFEul, *Var); - EXPECT_EQ(sizeof(uint64_t), Allocator.getBytesAllocated()); - EXPECT_TRUE(Allocator.getBytesAllocated() <= Allocator.getTotalMemory()); + EXPECT_LE(sizeof(uint64_t), Allocator.getTotalMemory()); PerThreadBumpPtrAllocator Allocator2(std::move(Allocator)); - EXPECT_EQ(sizeof(uint64_t), Allocator2.getBytesAllocated()); - EXPECT_TRUE(Allocator2.getBytesAllocated() <= Allocator2.getTotalMemory()); + EXPECT_LE(sizeof(uint64_t), Allocator2.getTotalMemory()); EXPECT_EQ(0xFEul, *Var); }); @@ -49,7 +47,7 @@ TEST(PerThreadBumpPtrAllocatorTest, ParallelAllocation) { *ptr = Idx; }); - EXPECT_EQ(sizeof(uint64_t) * NumAllocations, Allocator.getBytesAllocated()); + EXPECT_LE(sizeof(uint64_t) * NumAllocations, Allocator.getTotalMemory()); EXPECT_EQ(Allocator.getNumberOfAllocators(), parallel::getThreadCount()); } diff --git a/llvm/unittests/Support/ThreadSafeAllocatorTest.cpp b/llvm/unittests/Support/ThreadSafeAllocatorTest.cpp index b3d9430fc0f30..107a3a8b59cca 100644 --- a/llvm/unittests/Support/ThreadSafeAllocatorTest.cpp +++ b/llvm/unittests/Support/ThreadSafeAllocatorTest.cpp @@ -117,7 +117,7 @@ TEST(ThreadSafeAllocatorTest, AllocWithAlign) { Threads.wait(); Alloc.applyLocked([](BumpPtrAllocator &Alloc) { - EXPECT_EQ(4950U * sizeof(int), Alloc.getBytesAllocated()); + EXPECT_LE(4950U * sizeof(int), Alloc.getTotalMemory()); }); } diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp index 8668ea86a6ef9..d507cf2e74051 100644 --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -856,7 +856,7 @@ static void DumpEllipsisOrElidedLines(raw_ostream &OS, std::string &ElidedLines, unsigned EllipsisLines = 3; if (EllipsisLines < StringRef(ElidedLines).count('\n')) { for (unsigned i = 0; i < EllipsisLines; ++i) { - WithColor(OS, raw_ostream::BLACK, /*Bold=*/true) + WithColor(OS, raw_ostream::BRIGHT_BLACK, /*Bold=*/true) << right_justify(".", LabelWidthGlobal); OS << '\n'; } @@ -980,7 +980,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req, } // Print right-aligned line number. - WithColor(*LineOS, raw_ostream::BLACK, /*Bold=*/true, /*BF=*/false, + WithColor(*LineOS, raw_ostream::BRIGHT_BLACK, /*Bold=*/true, /*BG=*/false, TheColorMode) << format_decimal(Line, LabelWidthGlobal) << ": "; @@ -1003,8 +1003,16 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req, WithColor COS(*LineOS, raw_ostream::SAVEDCOLOR, /*Bold=*/false, /*BG=*/false, TheColorMode); bool InMatch = false; - if (Req.Verbose) - COS.changeColor(raw_ostream::CYAN, true, true); + if (Req.Verbose) { + COS.changeColor(raw_ostream::CYAN, /*Bold=*/true, /*BG=*/true); + } else { + // Our goal is to use the output streams's default color so that input + // text is legibile in both light and dark themes. SAVEDCOLOR above + // currently ignores the Bold=false there, so we override it with + // resetColor here, which ensures consistent colors with the resetColor + // below anyway. + COS.resetColor(); + } for (unsigned Col = 1; InputFilePtr != InputFileEnd && !Newline; ++Col) { bool WasInMatch = InMatch; InMatch = false; @@ -1014,6 +1022,8 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req, break; } } + // If !Req.Verbose, FoundAndExpectedMatches is empty, so InMatch and + // WasInMatch remain false, so these color transitions never happen. if (!WasInMatch && InMatch) COS.resetColor(); else if (WasInMatch && !InMatch) diff --git a/mlir/include/mlir-c/IR.h b/mlir/include/mlir-c/IR.h index fdff79f8b67dd..311234e42df60 100644 --- a/mlir/include/mlir-c/IR.h +++ b/mlir/include/mlir-c/IR.h @@ -59,6 +59,7 @@ DEFINE_C_API_STRUCT(MlirOpPrintingFlags, void); DEFINE_C_API_STRUCT(MlirBlock, void); DEFINE_C_API_STRUCT(MlirRegion, void); DEFINE_C_API_STRUCT(MlirSymbolTable, void); +DEFINE_C_API_STRUCT(MlirIRMapping, void); DEFINE_C_API_STRUCT(MlirAttribute, const void); DEFINE_C_API_STRUCT(MlirIdentifier, const void); @@ -1302,6 +1303,94 @@ MLIR_CAPI_EXPORTED void mlirSymbolTableWalkSymbolTables( MlirOperation from, bool allSymUsesVisible, void (*callback)(MlirOperation, bool, void *userData), void *userData); +//===----------------------------------------------------------------------===// +// IRMapping API +//===----------------------------------------------------------------------===// + +/// Creates a new empty IRMapping. +MLIR_CAPI_EXPORTED MlirIRMapping mlirIRMappingCreate(void); + +/// Destroys the given IRMapping. +MLIR_CAPI_EXPORTED void mlirIRMappingDestroy(MlirIRMapping mapping); + +/// Checks whether an IRMapping is null. +static inline bool mlirIRMappingIsNull(MlirIRMapping mapping) { + return !mapping.ptr; +} + +/// Maps a Value in the mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingMapValue(MlirIRMapping mapping, + MlirValue from, MlirValue to); + +/// Maps a Block in the mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingMapBlock(MlirIRMapping mapping, + MlirBlock from, MlirBlock to); + +/// Maps an Operation in the mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingMapOperation(MlirIRMapping mapping, + MlirOperation from, + MlirOperation to); + +/// Clears all mappings. +MLIR_CAPI_EXPORTED void mlirIRMappingClear(MlirIRMapping mapping); + +/// Looks up a mapped Value. Returns the mapped value, or the input value if +/// no mapping exists. +MLIR_CAPI_EXPORTED MlirValue +mlirIRMappingLookupOrDefaultValue(MlirIRMapping mapping, MlirValue from); + +/// Looks up a mapped Value. Returns a null MlirValue if no mapping exists. +MLIR_CAPI_EXPORTED MlirValue +mlirIRMappingLookupOrNullValue(MlirIRMapping mapping, MlirValue from); + +/// Looks up a mapped Block. Returns the mapped block, or the input block if +/// no mapping exists. +MLIR_CAPI_EXPORTED MlirBlock +mlirIRMappingLookupOrDefaultBlock(MlirIRMapping mapping, MlirBlock from); + +/// Looks up a mapped Block. Returns a null MlirBlock if no mapping exists. +MLIR_CAPI_EXPORTED MlirBlock +mlirIRMappingLookupOrNullBlock(MlirIRMapping mapping, MlirBlock from); + +/// Looks up a mapped Operation. Returns the mapped operation, or the input +/// operation if no mapping exists. +MLIR_CAPI_EXPORTED MlirOperation mlirIRMappingLookupOrDefaultOperation( + MlirIRMapping mapping, MlirOperation from); + +/// Looks up a mapped Operation. Returns a null MlirOperation if no mapping +/// exists. +MLIR_CAPI_EXPORTED MlirOperation +mlirIRMappingLookupOrNullOperation(MlirIRMapping mapping, MlirOperation from); + +/// Returns true if the mapping contains a mapping for the given value. +MLIR_CAPI_EXPORTED bool mlirIRMappingContainsValue(MlirIRMapping mapping, + MlirValue value); + +/// Returns true if the mapping contains a mapping for the given block. +MLIR_CAPI_EXPORTED bool mlirIRMappingContainsBlock(MlirIRMapping mapping, + MlirBlock block); + +/// Returns true if the mapping contains a mapping for the given operation. +MLIR_CAPI_EXPORTED bool mlirIRMappingContainsOperation(MlirIRMapping mapping, + MlirOperation op); + +/// Erases a value mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingEraseValue(MlirIRMapping mapping, + MlirValue value); + +/// Erases a block mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingEraseBlock(MlirIRMapping mapping, + MlirBlock block); + +/// Erases an operation mapping. +MLIR_CAPI_EXPORTED void mlirIRMappingEraseOperation(MlirIRMapping mapping, + MlirOperation op); + +/// Clones the operation with the given mapping. The mapping is updated with +/// the cloned operation's results and regions. +MLIR_CAPI_EXPORTED MlirOperation +mlirOperationCloneWithMapping(MlirOperation op, MlirIRMapping mapping); + #ifdef __cplusplus } #endif diff --git a/mlir/include/mlir-c/Rewrite.h b/mlir/include/mlir-c/Rewrite.h index 2e12f9cabbddd..ac243a4c9d8f9 100644 --- a/mlir/include/mlir-c/Rewrite.h +++ b/mlir/include/mlir-c/Rewrite.h @@ -161,6 +161,11 @@ mlirRewriterBaseClone(MlirRewriterBase rewriter, MlirOperation op); MLIR_CAPI_EXPORTED MlirOperation mlirRewriterBaseCloneWithoutRegions( MlirRewriterBase rewriter, MlirOperation op); +/// Clones the given operation using the rewriter and the provided IRMapping. +/// The mapping is updated with the results of the cloned operation. +MLIR_CAPI_EXPORTED MlirOperation mlirRewriterBaseCloneWithMapping( + MlirRewriterBase rewriter, MlirOperation op, MlirIRMapping mapping); + /// Clone the blocks that belong to "region" before the given position in /// another region "parent". MLIR_CAPI_EXPORTED void diff --git a/mlir/include/mlir/CAPI/IRMapping.h b/mlir/include/mlir/CAPI/IRMapping.h new file mode 100644 index 0000000000000..dc0a76490d8a6 --- /dev/null +++ b/mlir/include/mlir/CAPI/IRMapping.h @@ -0,0 +1,18 @@ +//===- IRMapping.h - C API wrap/unwrap for IRMapping -------------*- 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 MLIR_CAPI_IRMAPPING_H +#define MLIR_CAPI_IRMAPPING_H + +#include "mlir-c/IR.h" +#include "mlir/CAPI/Wrap.h" +#include "mlir/IR/IRMapping.h" + +DEFINE_C_API_PTR_METHODS(MlirIRMapping, mlir::IRMapping) + +#endif // MLIR_CAPI_IRMAPPING_H diff --git a/mlir/lib/CAPI/IR/IR.cpp b/mlir/lib/CAPI/IR/IR.cpp index 28ca830270366..94442e2be19a4 100644 --- a/mlir/lib/CAPI/IR/IR.cpp +++ b/mlir/lib/CAPI/IR/IR.cpp @@ -12,6 +12,7 @@ #include "mlir/AsmParser/AsmParser.h" #include "mlir/Bytecode/BytecodeWriter.h" #include "mlir/CAPI/IR.h" +#include "mlir/CAPI/IRMapping.h" #include "mlir/CAPI/Support.h" #include "mlir/CAPI/Utils.h" #include "mlir/IR/Attributes.h" @@ -1409,3 +1410,87 @@ void mlirSymbolTableWalkSymbolTables(MlirOperation from, bool allSymUsesVisible, userData); }); } + +//===----------------------------------------------------------------------===// +// IRMapping API +//===----------------------------------------------------------------------===// + +MlirIRMapping mlirIRMappingCreate(void) { return wrap(new IRMapping()); } + +void mlirIRMappingDestroy(MlirIRMapping mapping) { delete unwrap(mapping); } + +void mlirIRMappingMapValue(MlirIRMapping mapping, MlirValue from, + MlirValue to) { + unwrap(mapping)->map(unwrap(from), unwrap(to)); +} + +void mlirIRMappingMapBlock(MlirIRMapping mapping, MlirBlock from, + MlirBlock to) { + unwrap(mapping)->map(unwrap(from), unwrap(to)); +} + +void mlirIRMappingMapOperation(MlirIRMapping mapping, MlirOperation from, + MlirOperation to) { + unwrap(mapping)->map(unwrap(from), unwrap(to)); +} + +void mlirIRMappingClear(MlirIRMapping mapping) { unwrap(mapping)->clear(); } + +MlirValue mlirIRMappingLookupOrDefaultValue(MlirIRMapping mapping, + MlirValue from) { + return wrap(unwrap(mapping)->lookupOrDefault(unwrap(from))); +} + +MlirValue mlirIRMappingLookupOrNullValue(MlirIRMapping mapping, + MlirValue from) { + return wrap(unwrap(mapping)->lookupOrNull(unwrap(from))); +} + +MlirBlock mlirIRMappingLookupOrDefaultBlock(MlirIRMapping mapping, + MlirBlock from) { + return wrap(unwrap(mapping)->lookupOrDefault(unwrap(from))); +} + +MlirBlock mlirIRMappingLookupOrNullBlock(MlirIRMapping mapping, + MlirBlock from) { + return wrap(unwrap(mapping)->lookupOrNull(unwrap(from))); +} + +MlirOperation mlirIRMappingLookupOrDefaultOperation(MlirIRMapping mapping, + MlirOperation from) { + return wrap(unwrap(mapping)->lookupOrDefault(unwrap(from))); +} + +MlirOperation mlirIRMappingLookupOrNullOperation(MlirIRMapping mapping, + MlirOperation from) { + return wrap(unwrap(mapping)->lookupOrNull(unwrap(from))); +} + +bool mlirIRMappingContainsValue(MlirIRMapping mapping, MlirValue value) { + return unwrap(mapping)->contains(unwrap(value)); +} + +bool mlirIRMappingContainsBlock(MlirIRMapping mapping, MlirBlock block) { + return unwrap(mapping)->contains(unwrap(block)); +} + +bool mlirIRMappingContainsOperation(MlirIRMapping mapping, MlirOperation op) { + return unwrap(mapping)->contains(unwrap(op)); +} + +void mlirIRMappingEraseValue(MlirIRMapping mapping, MlirValue value) { + unwrap(mapping)->erase(unwrap(value)); +} + +void mlirIRMappingEraseBlock(MlirIRMapping mapping, MlirBlock block) { + unwrap(mapping)->erase(unwrap(block)); +} + +void mlirIRMappingEraseOperation(MlirIRMapping mapping, MlirOperation op) { + unwrap(mapping)->erase(unwrap(op)); +} + +MlirOperation mlirOperationCloneWithMapping(MlirOperation op, + MlirIRMapping mapping) { + return wrap(unwrap(op)->clone(*unwrap(mapping))); +} diff --git a/mlir/lib/CAPI/Transforms/Rewrite.cpp b/mlir/lib/CAPI/Transforms/Rewrite.cpp index 4f75cc758bc48..56ce9212f4811 100644 --- a/mlir/lib/CAPI/Transforms/Rewrite.cpp +++ b/mlir/lib/CAPI/Transforms/Rewrite.cpp @@ -11,6 +11,7 @@ #include "mlir-c/Support.h" #include "mlir-c/Transforms.h" #include "mlir/CAPI/IR.h" +#include "mlir/CAPI/IRMapping.h" #include "mlir/CAPI/Rewrite.h" #include "mlir/CAPI/Support.h" #include "mlir/CAPI/Wrap.h" @@ -118,6 +119,12 @@ MlirOperation mlirRewriterBaseCloneWithoutRegions(MlirRewriterBase rewriter, return wrap(unwrap(rewriter)->cloneWithoutRegions(*unwrap(op))); } +MlirOperation mlirRewriterBaseCloneWithMapping(MlirRewriterBase rewriter, + MlirOperation op, + MlirIRMapping mapping) { + return wrap(unwrap(rewriter)->clone(*unwrap(op), *unwrap(mapping))); +} + void mlirRewriterBaseCloneRegionBefore(MlirRewriterBase rewriter, MlirRegion region, MlirBlock before) { diff --git a/mlir/test/CAPI/ir.c b/mlir/test/CAPI/ir.c index ec0a877f830dd..d8a252a426f19 100644 --- a/mlir/test/CAPI/ir.c +++ b/mlir/test/CAPI/ir.c @@ -2623,6 +2623,125 @@ int testInterfaces(MlirContext ctx) { return 0; } +int testIRMapping(MlirContext ctx) { + fprintf(stderr, "@testIRMapping\n"); + // CHECK-LABEL: @testIRMapping + + mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith")); + + MlirIRMapping mapping = mlirIRMappingCreate(); + assert(!mlirIRMappingIsNull(mapping)); + + const char *moduleStr = "func.func @f(%arg0: i32, %arg1: i32) -> i32 {\n" + " %0 = arith.addi %arg0, %arg1 : i32\n" + " return %0 : i32\n" + "}\n"; + MlirModule module = + mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleStr)); + + MlirBlock moduleBody = mlirModuleGetBody(module); + MlirOperation funcOp = mlirBlockGetFirstOperation(moduleBody); + MlirRegion funcRegion = mlirOperationGetRegion(funcOp, 0); + MlirBlock funcBody = mlirRegionGetFirstBlock(funcRegion); + MlirValue arg0 = mlirBlockGetArgument(funcBody, 0); + MlirValue arg1 = mlirBlockGetArgument(funcBody, 1); + MlirOperation addOp = mlirBlockGetFirstOperation(funcBody); + MlirValue addResult = mlirOperationGetResult(addOp, 0); + + // --- Task 1: Map --- + + mlirIRMappingMapValue(mapping, arg0, addResult); + mlirIRMappingMapBlock(mapping, funcBody, moduleBody); + mlirIRMappingMapOperation(mapping, addOp, funcOp); + + // --- Task 2: Lookup --- + + // Value lookup: mapped + MlirValue looked = mlirIRMappingLookupOrDefaultValue(mapping, arg0); + assert(mlirValueEqual(looked, addResult)); + + // Value lookup: unmapped returns default (the input itself) + MlirValue defaulted = mlirIRMappingLookupOrDefaultValue(mapping, arg1); + assert(mlirValueEqual(defaulted, arg1)); + + // Value lookup: unmapped returns null + MlirValue nullVal = mlirIRMappingLookupOrNullValue(mapping, arg1); + assert(mlirValueIsNull(nullVal)); + + // Block lookup: mapped + MlirBlock lookedBlock = mlirIRMappingLookupOrDefaultBlock(mapping, funcBody); + assert(mlirBlockEqual(lookedBlock, moduleBody)); + + // Operation lookup: mapped + MlirOperation lookedOp = + mlirIRMappingLookupOrDefaultOperation(mapping, addOp); + assert(mlirOperationEqual(lookedOp, funcOp)); + + // --- Task 3: Contains and Erase --- + + assert(mlirIRMappingContainsValue(mapping, arg0)); + assert(mlirIRMappingContainsBlock(mapping, funcBody)); + assert(mlirIRMappingContainsOperation(mapping, addOp)); + assert(!mlirIRMappingContainsValue(mapping, arg1)); + + // Erase value + mlirIRMappingEraseValue(mapping, arg0); + assert(!mlirIRMappingContainsValue(mapping, arg0)); + + // Erase block + mlirIRMappingEraseBlock(mapping, funcBody); + assert(!mlirIRMappingContainsBlock(mapping, funcBody)); + + // Erase operation + mlirIRMappingEraseOperation(mapping, addOp); + assert(!mlirIRMappingContainsOperation(mapping, addOp)); + + // Block lookup: unmapped returns null + MlirBlock nullBlock = mlirIRMappingLookupOrNullBlock(mapping, funcBody); + assert(mlirBlockIsNull(nullBlock)); + + // Operation lookup: unmapped returns null + MlirOperation nullOp = mlirIRMappingLookupOrNullOperation(mapping, addOp); + assert(mlirOperationIsNull(nullOp)); + + // Clear + mlirIRMappingMapValue(mapping, arg0, addResult); + mlirIRMappingClear(mapping); + assert(!mlirIRMappingContainsValue(mapping, arg0)); + + // --- Task 4: Clone with mapping --- + + MlirIRMapping cloneMapping = mlirIRMappingCreate(); + mlirIRMappingMapValue(cloneMapping, arg0, arg1); + mlirIRMappingMapValue(cloneMapping, arg1, arg0); + + MlirOperation cloned = mlirOperationCloneWithMapping(addOp, cloneMapping); + assert(!mlirOperationIsNull(cloned)); + assert(mlirIRMappingContainsValue(cloneMapping, addResult)); + + // The cloned op should have its operands remapped + MlirValue clonedOp0 = mlirOperationGetOperand(cloned, 0); + MlirValue clonedOp1 = mlirOperationGetOperand(cloned, 1); + assert(mlirValueEqual(clonedOp0, arg1)); + assert(mlirValueEqual(clonedOp1, arg0)); + + // The original op should have its result remapped + MlirValue mappedValue = + mlirIRMappingLookupOrNullValue(cloneMapping, addResult); + assert(!mlirValueIsNull(mappedValue)); + MlirValue clonedResult = mlirOperationGetResult(cloned, 0); + assert(mlirValueEqual(clonedResult, mappedValue)); + + mlirOperationDestroy(cloned); + mlirIRMappingDestroy(cloneMapping); + mlirIRMappingDestroy(mapping); + mlirModuleDestroy(module); + + // CHECK: testIRMapping: PASSED + fprintf(stderr, "testIRMapping: PASSED\n"); + return 0; +} + int main(void) { MlirContext ctx = mlirContextCreate(); registerAllUpstreamDialects(ctx); @@ -2674,6 +2793,8 @@ int main(void) { return 17; if (testInterfaces(ctx)) return 18; + if (testIRMapping(ctx)) + return 19; // CHECK: DESTROY MAIN CONTEXT // CHECK: reportResourceDelete: resource_i64_blob diff --git a/mlir/test/CAPI/rewrite.c b/mlir/test/CAPI/rewrite.c index 48d70579fa325..3809dd6a7843f 100644 --- a/mlir/test/CAPI/rewrite.c +++ b/mlir/test/CAPI/rewrite.c @@ -581,6 +581,48 @@ void testGreedyRewriteDriverConfig(MlirContext ctx) { mlirGreedyRewriteDriverConfigDestroy(config); } +void testCloneWithMapping(MlirContext ctx) { + // CHECK-LABEL: @testCloneWithMapping + fprintf(stderr, "@testCloneWithMapping\n"); + + const char *moduleString = + "%x, %y = \"dialect.create_values\"() : () -> (index, index)\n" + "%sum = \"dialect.add\"(%x, %y) : (index, index) -> index\n"; + MlirModule module = + mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString)); + MlirBlock body = mlirModuleGetBody(module); + + MlirOperation createValues = mlirBlockGetFirstOperation(body); + MlirValue x = mlirOperationGetResult(createValues, 0); + MlirValue y = mlirOperationGetResult(createValues, 1); + MlirOperation addOp = mlirOperationGetNextInBlock(createValues); + + MlirRewriterBase rewriter = mlirIRRewriterCreate(ctx); + mlirRewriterBaseSetInsertionPointAfter(rewriter, addOp); + + // Clone addOp with a mapping that swaps x -> y, y -> x + MlirIRMapping mapping = mlirIRMappingCreate(); + mlirIRMappingMapValue(mapping, x, y); + mlirIRMappingMapValue(mapping, y, x); + + MlirOperation cloned = + mlirRewriterBaseCloneWithMapping(rewriter, addOp, mapping); + assert(!mlirOperationIsNull(cloned)); + + // Verify operands are remapped + MlirValue clonedOp0 = mlirOperationGetOperand(cloned, 0); + MlirValue clonedOp1 = mlirOperationGetOperand(cloned, 1); + assert(mlirValueEqual(clonedOp0, y)); + assert(mlirValueEqual(clonedOp1, x)); + + mlirIRMappingDestroy(mapping); + mlirIRRewriterDestroy(rewriter); + mlirModuleDestroy(module); + + // CHECK: testCloneWithMapping: PASSED + fprintf(stderr, "testCloneWithMapping: PASSED\n"); +} + int main(void) { MlirContext ctx = mlirContextCreate(); mlirContextSetAllowUnregisteredDialects(ctx, true); @@ -595,6 +637,7 @@ int main(void) { testOpModification(ctx); testReplaceUses(ctx); testGreedyRewriteDriverConfig(ctx); + testCloneWithMapping(ctx); mlirContextDestroy(ctx); return 0; diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index d524fe69b8c89..87d32d0fa5022 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -525,6 +525,7 @@ mlir_c_api_cc_library( "include/mlir/CAPI/AffineMap.h", "include/mlir/CAPI/Diagnostics.h", "include/mlir/CAPI/IR.h", + "include/mlir/CAPI/IRMapping.h", "include/mlir/CAPI/IntegerSet.h", "include/mlir/CAPI/Interfaces.h", "include/mlir/CAPI/Pass.h",