[llvm] 8c386c9 - [SmallVector] Move error handling out of line

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 6 09:11:22 PDT 2020


Author: Benjamin Kramer
Date: 2020-09-06T18:06:44+02:00
New Revision: 8c386c94749a78392fd763f8449ca3e55f030ffd

URL: https://github.com/llvm/llvm-project/commit/8c386c94749a78392fd763f8449ca3e55f030ffd
DIFF: https://github.com/llvm/llvm-project/commit/8c386c94749a78392fd763f8449ca3e55f030ffd.diff

LOG: [SmallVector] Move error handling out of line

This reduces duplication and avoids emitting ice cold code into every
instance of grow().

Added: 
    

Modified: 
    llvm/include/llvm/ADT/SmallVector.h
    llvm/lib/Support/SmallVector.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 8197b8688a52..c3c6a366dab2 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -32,9 +32,6 @@
 #include <new>
 #include <type_traits>
 #include <utility>
-#ifdef LLVM_ENABLE_EXCEPTIONS
-#include <stdexcept>
-#endif
 
 namespace llvm {
 
@@ -65,6 +62,13 @@ template <class Size_T> class SmallVectorBase {
   /// This function will report a fatal error if it cannot increase capacity.
   void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
 
+  /// Report that MinSize doesn't fit into this vector's size type. Throws
+  /// std::length_error or calls report_fatal_error.
+  LLVM_ATTRIBUTE_NORETURN static void report_size_overflow(size_t MinSize);
+  /// Report that this vector is already at maximum capacity. Throws
+  /// std::length_error or calls report_fatal_error.
+  LLVM_ATTRIBUTE_NORETURN static void report_at_maximum_capacity();
+
 public:
   size_t size() const { return Size; }
   size_t capacity() const { return Capacity; }
@@ -271,32 +275,16 @@ template <typename T, bool TriviallyCopyable>
 void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
   // Ensure we can fit the new capacity.
   // This is only going to be applicable when the capacity is 32 bit.
-  if (MinSize > this->SizeTypeMax()) {
-    std::string Reason = "SmallVector unable to grow. Requested capacity (" +
-                         std::to_string(MinSize) +
-                         ") is larger than maximum value for size type (" +
-                         std::to_string(this->SizeTypeMax()) + ")";
-#ifdef LLVM_ENABLE_EXCEPTIONS
-    throw std::length_error(Reason);
-#else
-    report_fatal_error(Reason);
-#endif
-  }
+  if (MinSize > this->SizeTypeMax())
+    this->report_size_overflow(MinSize);
 
   // Ensure we can meet the guarantee of space for at least one more element.
   // The above check alone will not catch the case where grow is called with a
   // default MinSize of 0, but the current capacity cannot be increased.
   // This is only going to be applicable when the capacity is 32 bit.
-  if (this->capacity() == this->SizeTypeMax()) {
-    std::string Reason =
-        "SmallVector capacity unable to grow. Already at maximum size " +
-        std::to_string(this->SizeTypeMax());
-#ifdef LLVM_ENABLE_EXCEPTIONS
-    throw std::length_error(Reason);
-#else
-    report_fatal_error(Reason);
-#endif
-  }
+  if (this->capacity() == this->SizeTypeMax())
+    this->report_at_maximum_capacity();
+
   // Always grow, even from zero.
   size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
   NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());

diff  --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
index 73137640536c..debde5cdad5b 100644
--- a/llvm/lib/Support/SmallVector.cpp
+++ b/llvm/lib/Support/SmallVector.cpp
@@ -12,6 +12,9 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include <cstdint>
+#ifdef LLVM_ENABLE_EXCEPTIONS
+#include <stdexcept>
+#endif
 using namespace llvm;
 
 // Check that no bytes are wasted and everything is well-aligned.
@@ -42,37 +45,45 @@ static_assert(sizeof(SmallVector<char, 0>) ==
                   sizeof(void *) * 2 + sizeof(void *),
               "1 byte elements have word-sized type for size and capacity");
 
+template <class Size_T>
+void SmallVectorBase<Size_T>::report_size_overflow(size_t MinSize) {
+  std::string Reason = "SmallVector unable to grow. Requested capacity (" +
+                       std::to_string(MinSize) +
+                       ") is larger than maximum value for size type (" +
+                       std::to_string(SizeTypeMax()) + ")";
+#ifdef LLVM_ENABLE_EXCEPTIONS
+  throw std::length_error(Reason);
+#else
+  report_fatal_error(Reason);
+#endif
+}
+
+template <class Size_T> void SmallVectorBase<Size_T>::report_at_maximum_capacity() {
+  std::string Reason =
+      "SmallVector capacity unable to grow. Already at maximum size " +
+      std::to_string(SizeTypeMax());
+#ifdef LLVM_ENABLE_EXCEPTIONS
+  throw std::length_error(Reason);
+#else
+  report_fatal_error(Reason);
+#endif
+}
+
 // Note: Moving this function into the header may cause performance regression.
 template <class Size_T>
 void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
                                        size_t TSize) {
   // Ensure we can fit the new capacity.
   // This is only going to be applicable when the capacity is 32 bit.
-  if (MinSize > SizeTypeMax()) {
-    std::string Reason = "SmallVector unable to grow. Requested capacity (" +
-                         std::to_string(MinSize) +
-                         ") is larger than maximum value for size type (" +
-                         std::to_string(SizeTypeMax()) + ")";
-#ifdef LLVM_ENABLE_EXCEPTIONS
-    throw std::length_error(Reason);
-#else
-    report_fatal_error(Reason);
-#endif
-  }
+  if (MinSize > SizeTypeMax())
+    report_size_overflow(MinSize);
 
   // Ensure we can meet the guarantee of space for at least one more element.
   // The above check alone will not catch the case where grow is called with a
   // default MinSize of 0, but the current capacity cannot be increased.
   // This is only going to be applicable when the capacity is 32 bit.
-  if (capacity() == SizeTypeMax()) {
-    std::string Reason =
-        "SmallVector capacity unable to grow. Already at maximum size " +
-        std::to_string(SizeTypeMax());
-#ifdef LLVM_ENABLE_EXCEPTIONS
-    throw std::length_error(Reason);
-#endif
-    report_fatal_error(Reason);
-  }
+  if (capacity() == SizeTypeMax())
+    report_at_maximum_capacity();
 
   // In theory 2*capacity can overflow if the capacity is 64 bit, but the
   // original capacity would never be large enough for this to be a problem.


        


More information about the llvm-commits mailing list