[llvm] 8423a6f - Rename OptimalLayout to OptimizedStructLayout at Chris's request.

John McCall via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 21:14:28 PDT 2020


Author: John McCall
Date: 2020-04-10T00:14:20-04:00
New Revision: 8423a6f36386aabced2a367c0ea53487901d31ca

URL: https://github.com/llvm/llvm-project/commit/8423a6f36386aabced2a367c0ea53487901d31ca
DIFF: https://github.com/llvm/llvm-project/commit/8423a6f36386aabced2a367c0ea53487901d31ca.diff

LOG: Rename OptimalLayout to OptimizedStructLayout at Chris's request.

Added: 
    llvm/include/llvm/Support/OptimizedStructLayout.h
    llvm/lib/Support/OptimizedStructLayout.cpp
    llvm/unittests/Support/OptimizedStructLayoutTest.cpp

Modified: 
    llvm/lib/Support/CMakeLists.txt
    llvm/lib/Transforms/Coroutines/CoroFrame.cpp
    llvm/unittests/Support/CMakeLists.txt
    llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
    llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn

Removed: 
    llvm/include/llvm/Support/OptimalLayout.h
    llvm/lib/Support/OptimalLayout.cpp
    llvm/unittests/Support/OptimalLayoutTest.cpp


################################################################################
diff  --git a/llvm/include/llvm/Support/OptimalLayout.h b/llvm/include/llvm/Support/OptimizedStructLayout.h
similarity index 74%
rename from llvm/include/llvm/Support/OptimalLayout.h
rename to llvm/include/llvm/Support/OptimizedStructLayout.h
index 870dc78791bb..773ddfeaf13a 100644
--- a/llvm/include/llvm/Support/OptimalLayout.h
+++ b/llvm/include/llvm/Support/OptimizedStructLayout.h
@@ -1,4 +1,4 @@
-//===-- OptimalLayout.h - Optimal data layout algorithm -----------*- C++ -*-=//
+//===-- OptimizedStructLayout.h - Struct layout algorithm ---------*- C++ -*-=//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -8,19 +8,31 @@
 ///
 /// This file provides an interface for laying out a sequence of fields
 /// as a struct in a way that attempts to minimizes the total space
-/// requirements of the struct.
+/// requirements of the struct while still satisfying the layout
+/// requirements of the individual fields.  The resulting layout may be
+/// substantially more compact than simply laying out the fields in their
+/// original order.
 ///
-/// The word "optimal" is a misnomer in several ways.  First, minimizing
-/// space usage doesn't necessarily yield optimal performance because it
-/// may decrease locality.  Second, there is no known efficient algorithm
-/// that guarantees a minimal layout for arbitrary inputs.  Nonetheless,
-/// this algorithm is likely to produce much more compact layouts than
-/// would be produced by just allocating space in a buffer.
+/// Fields may be pre-assigned fixed offsets.  They may also be given sizes
+/// that are not multiples of their alignments.  There is no currently no
+/// way to describe that a field has interior padding that other fields may
+/// be allocated into.
+///
+/// This algorithm does not claim to be "optimal" for several reasons:
+///
+/// - First, it does not guarantee that the result is minimal in size.
+///   There is no known efficient algoorithm to achieve minimality for
+///   unrestricted inputs.  Nonetheless, this algorithm 
+///
+/// - Second, there are other ways that a struct layout could be optimized
+///   besides space usage, such as locality.  This layout may have a mixed
+///   impact on locality: less overall memory may be used, but adjacent
+///   fields in the original array may be moved further from one another.
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_SUPPORT_OPTIMALLAYOUT_H
-#define LLVM_SUPPORT_OPTIMALLAYOUT_H
+#ifndef LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
+#define LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
 
 #include "llvm/Support/Alignment.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -29,13 +41,13 @@
 namespace llvm {
 
 /// A field in a structure.
-struct OptimalLayoutField {
+struct OptimizedStructLayoutField {
   /// A special value for Offset indicating that the field can be moved
   /// anywhere.
   static constexpr uint64_t FlexibleOffset = ~(uint64_t)0;
 
-  OptimalLayoutField(const void *Id, uint64_t Size, Align Alignment,
-                     uint64_t FixedOffset = FlexibleOffset)
+  OptimizedStructLayoutField(const void *Id, uint64_t Size, Align Alignment,
+                             uint64_t FixedOffset = FlexibleOffset)
       : Offset(FixedOffset), Size(Size), Id(Id), Alignment(Alignment) {
     assert(Size > 0 && "adding an empty field to the layout");
   }
@@ -122,8 +134,8 @@ struct OptimalLayoutField {
 /// The return value is the total size of the struct and its required
 /// alignment.  Note that the total size is not rounded up to a multiple
 /// of the required alignment; clients which require this can do so easily.
-std::pair<uint64_t, Align>
-performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields);
+std::pair<uint64_t, Align> performOptimizedStructLayout(
+                        MutableArrayRef<OptimizedStructLayoutField> Fields);
 
 } // namespace llvm
 

diff  --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 25e1be673300..897f183b660f 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -117,7 +117,7 @@ add_llvm_component_library(LLVMSupport
   MemoryBuffer.cpp
   MD5.cpp
   NativeFormatting.cpp
-  OptimalLayout.cpp
+  OptimizedStructLayout.cpp
   Optional.cpp
   Parallel.cpp
   PluginLoader.cpp

diff  --git a/llvm/lib/Support/OptimalLayout.cpp b/llvm/lib/Support/OptimizedStructLayout.cpp
similarity index 93%
rename from llvm/lib/Support/OptimalLayout.cpp
rename to llvm/lib/Support/OptimizedStructLayout.cpp
index 93f912bf73a3..9bbd767c5ce9 100644
--- a/llvm/lib/Support/OptimalLayout.cpp
+++ b/llvm/lib/Support/OptimizedStructLayout.cpp
@@ -1,4 +1,4 @@
-//===--- OptimalLayout.cpp - Optimal data layout algorithm ----------------===//
+//===--- OptimizedStructLayout.cpp - Optimal data layout algorithm ----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,16 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the performOptimalLayout interface.
+// This file implements the performOptimizedStructLayout interface.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Support/OptimalLayout.h"
+#include "llvm/Support/OptimizedStructLayout.h"
 
 using namespace llvm;
 
+using Field = OptimizedStructLayoutField;
+
 #ifndef NDEBUG
-static void checkValidLayout(ArrayRef<OptimalLayoutField> Fields, uint64_t Size,
+static void checkValidLayout(ArrayRef<Field> Fields, uint64_t Size,
                              Align MaxAlign) {
   uint64_t LastEnd = 0;
   Align ComputedMaxAlign;
@@ -37,7 +39,7 @@ static void checkValidLayout(ArrayRef<OptimalLayoutField> Fields, uint64_t Size,
 #endif
 
 std::pair<uint64_t, Align>
-llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
+llvm::performOptimizedStructLayout(MutableArrayRef<Field> Fields) {
 #ifndef NDEBUG
   // Do some simple precondition checks.
   {
@@ -101,8 +103,7 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
   // important if we get into the gap-filling stage below, but it
   // doesn't hurt here.
   array_pod_sort(FirstFlexible, E,
-                 [](const OptimalLayoutField *lhs,
-                    const OptimalLayoutField *rhs) -> int {
+                 [](const Field *lhs, const Field *rhs) -> int {
     // Decreasing alignment.
     if (lhs->Alignment != rhs->Alignment)
       return (lhs->Alignment < rhs->Alignment ? 1 : -1);
@@ -240,13 +241,13 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
     /// monotonically descending in size and otherwise in the original order.
     ///
     /// We remove the queue from the array as soon as this is empty.
-    OptimalLayoutField *Head;
+    OptimizedStructLayoutField *Head;
 
     /// The alignment requirement of the queue.
     Align Alignment;
 
-    static OptimalLayoutField *getNext(OptimalLayoutField *Cur) {
-      return static_cast<OptimalLayoutField*>(Cur->Scratch);
+    static Field *getNext(Field *Cur) {
+      return static_cast<Field *>(Cur->Scratch);
     }
   };
   SmallVector<AlignmentQueue, 8> FlexibleFieldsByAlignment;
@@ -290,9 +291,7 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
 #endif
 
   /// Helper function to remove a field from a queue.
-  auto spliceFromQueue = [&](AlignmentQueue *Queue,
-                             OptimalLayoutField *Last,
-                             OptimalLayoutField *Cur) {
+  auto spliceFromQueue = [&](AlignmentQueue *Queue, Field *Last, Field *Cur) {
     assert(Last ? Queue->getNext(Last) == Cur : Queue->Head == Cur);
 
     // If we're removing Cur from a non-initial position, splice it out
@@ -319,7 +318,7 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
 
   // Do layout into a local array.  Doing this in-place on Fields is
   // not really feasible.
-  SmallVector<OptimalLayoutField, 16> Layout;
+  SmallVector<Field, 16> Layout;
   Layout.reserve(Fields.size());
 
   // The offset that we're currently looking to insert at (or after).
@@ -327,9 +326,7 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
 
   // Helper function to splice Cur out of the given queue and add it
   // to the layout at the given offset.
-  auto addToLayout = [&](AlignmentQueue *Queue,
-                         OptimalLayoutField *Last,
-                         OptimalLayoutField *Cur,
+  auto addToLayout = [&](AlignmentQueue *Queue, Field *Last, Field *Cur,
                          uint64_t Offset) -> bool {
     assert(Offset == alignTo(LastEnd, Cur->Alignment));
 
@@ -362,8 +359,8 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
 
     // Find the matching field.  Note that this should always find
     // something because of the MinSize check above.
-    for (OptimalLayoutField *Cur = Queue->Head, *Last = nullptr;
-           true; Last = Cur, Cur = Queue->getNext(Cur)) {
+    for (Field *Cur = Queue->Head, *Last = nullptr; true;
+           Last = Cur, Cur = Queue->getNext(Cur)) {
       assert(Cur && "didn't find a match in queue despite its MinSize");
       if (Cur->Size <= MaxViableSize)
         return addToLayout(Queue, Last, Cur, StartOffset);
@@ -441,7 +438,7 @@ llvm::performOptimalLayout(MutableArrayRef<OptimalLayoutField> Fields) {
   // Copy the layout back into place.
   assert(Layout.size() == Fields.size());
   memcpy(Fields.data(), Layout.data(),
-         Fields.size() * sizeof(OptimalLayoutField));
+         Fields.size() * sizeof(OptimizedStructLayoutField));
 
 #ifndef NDEBUG
   // Make a final check that the layout is valid.

diff  --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index e166e28cbcdf..204a4697b705 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -29,7 +29,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/circular_raw_ostream.h"
-#include "llvm/Support/OptimalLayout.h"
+#include "llvm/Support/OptimizedStructLayout.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
@@ -412,7 +412,7 @@ class FrameTypeBuilder {
 
     // Everything else has a flexible offset.
     } else {
-      Offset = OptimalLayoutField::FlexibleOffset;
+      Offset = OptimizedStructLayoutField::FlexibleOffset;
     }
 
     Fields.push_back({FieldSize, Offset, ForSpill, Ty, 0,
@@ -445,7 +445,7 @@ void FrameTypeBuilder::finish(StructType *Ty) {
 
   // Prepare the optimal-layout field array.
   // The Id in the layout field is a pointer to our Field for it.
-  SmallVector<OptimalLayoutField, 8> LayoutFields;
+  SmallVector<OptimizedStructLayoutField, 8> LayoutFields;
   LayoutFields.reserve(Fields.size());
   for (auto &Field : Fields) {
     LayoutFields.emplace_back(&Field, Field.Size, Field.Alignment,
@@ -453,11 +453,11 @@ void FrameTypeBuilder::finish(StructType *Ty) {
   }
 
   // Perform layout.
-  auto SizeAndAlign = performOptimalLayout(LayoutFields);
+  auto SizeAndAlign = performOptimizedStructLayout(LayoutFields);
   StructSize = SizeAndAlign.first;
   StructAlign = SizeAndAlign.second;
 
-  auto getField = [](const OptimalLayoutField &LayoutField) -> Field & {
+  auto getField = [](const OptimizedStructLayoutField &LayoutField) -> Field & {
     return *static_cast<Field *>(const_cast<void*>(LayoutField.Id));
   };
 

diff  --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index a570a0406d72..b6ed410c0f7f 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -52,7 +52,7 @@ add_llvm_unittest(SupportTests
   MemoryBufferTest.cpp
   MemoryTest.cpp
   NativeFormatTests.cpp
-  OptimalLayoutTest.cpp
+  OptimizedStructLayoutTest.cpp
   ParallelTest.cpp
   Path.cpp
   ProcessTest.cpp

diff  --git a/llvm/unittests/Support/OptimalLayoutTest.cpp b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
similarity index 82%
rename from llvm/unittests/Support/OptimalLayoutTest.cpp
rename to llvm/unittests/Support/OptimizedStructLayoutTest.cpp
index a31fbaf3f2e6..26d5e27b14b0 100644
--- a/llvm/unittests/Support/OptimalLayoutTest.cpp
+++ b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
@@ -1,4 +1,4 @@
-//=== - llvm/unittest/Support/OptimalLayoutTest.cpp - Layout tests --------===//
+//=== - unittest/Support/OptimizedStructLayoutTest.cpp - Layout tests -----===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Support/OptimalLayout.h"
+#include "llvm/Support/OptimizedStructLayout.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -33,7 +33,7 @@ class LayoutTest {
   LayoutTest &flexible(uint64_t Size, uint64_t Alignment,
                        uint64_t ExpectedOffset) {
     Fields.push_back({Size, Align(Alignment),
-                      OptimalLayoutField::FlexibleOffset, ExpectedOffset});
+                      OptimizedStructLayoutField::FlexibleOffset, ExpectedOffset});
     return *this;
   }
 
@@ -43,12 +43,12 @@ class LayoutTest {
   }
 
   void verify(uint64_t ExpectedSize, uint64_t ExpectedAlignment) {
-    SmallVector<OptimalLayoutField, 8> LayoutFields;
+    SmallVector<OptimizedStructLayoutField, 8> LayoutFields;
     LayoutFields.reserve(Fields.size());
     for (auto &F : Fields)
       LayoutFields.emplace_back(&F, F.Size, F.Alignment, F.ForcedOffset);
 
-    auto SizeAndAlign = performOptimalLayout(LayoutFields);
+    auto SizeAndAlign = performOptimizedStructLayout(LayoutFields);
 
     EXPECT_EQ(SizeAndAlign.first, ExpectedSize);
     EXPECT_EQ(SizeAndAlign.second, Align(ExpectedAlignment));
@@ -64,7 +64,7 @@ class LayoutTest {
 
 }
 
-TEST(OptimalLayoutTest, Basic) {
+TEST(OptimizedStructLayoutTest, Basic) {
   LayoutTest()
     .flexible(12, 4, 8)
     .flexible(8,  8, 0)
@@ -72,7 +72,7 @@ TEST(OptimalLayoutTest, Basic) {
     .verify(24, 8);
 }
 
-TEST(OptimalLayoutTest, OddSize) {
+TEST(OptimizedStructLayoutTest, OddSize) {
   LayoutTest()
     .flexible(8,  8, 16)
     .flexible(4,  4, 12)
@@ -81,7 +81,7 @@ TEST(OptimalLayoutTest, OddSize) {
     .verify(24, 8);
 }
 
-TEST(OptimalLayoutTest, Gaps) {
+TEST(OptimizedStructLayoutTest, Gaps) {
   LayoutTest()
     .fixed(4, 4, 8)
     .fixed(4, 4, 16)
@@ -92,7 +92,7 @@ TEST(OptimalLayoutTest, Gaps) {
     .verify(24, 4);
 }
 
-TEST(OptimalLayoutTest, Greed) {
+TEST(OptimizedStructLayoutTest, Greed) {
   // The greedy algorithm doesn't find the optimal layout here, which
   // would be to put the 5-byte field at the end.
   LayoutTest()
@@ -104,7 +104,7 @@ TEST(OptimalLayoutTest, Greed) {
     .verify(24, 4);
 }
 
-TEST(OptimalLayoutTest, Jagged) {
+TEST(OptimizedStructLayoutTest, Jagged) {
   LayoutTest()
     .flexible(1, 2, 18)
     .flexible(13, 8, 0)
@@ -112,7 +112,7 @@ TEST(OptimalLayoutTest, Jagged) {
     .verify(19, 8);
 }
 
-TEST(OptimalLayoutTest, GardenPath) {
+TEST(OptimizedStructLayoutTest, GardenPath) {
   // The 4-byte-aligned field is our highest priority, but the less-aligned
   // fields keep leaving the end offset mis-aligned.
   LayoutTest()

diff  --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
index 13ffdaedfb66..33fac467a5c9 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
@@ -95,7 +95,7 @@ static_library("Support") {
     "MathExtras.cpp",
     "MemoryBuffer.cpp",
     "NativeFormatting.cpp",
-    "OptimalLayout.cpp",
+    "OptimizedStructLayout.cpp",
     "Optional.cpp",
     "Parallel.cpp",
     "PluginLoader.cpp",

diff  --git a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
index c25323955b96..b58a6aba73d7 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
@@ -55,7 +55,7 @@ unittest("SupportTests") {
     "MemoryBufferTest.cpp",
     "MemoryTest.cpp",
     "NativeFormatTests.cpp",
-    "OptimalLayoutTest.cpp",
+    "OptimizedStructLayoutTest.cpp",
     "ParallelTest.cpp",
     "Path.cpp",
     "ProcessTest.cpp",


        


More information about the llvm-commits mailing list