[Lldb-commits] [lldb] 101f37a - [lldb][NFC] Rewrite CPP11EnumTypes test to make it faster

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 4 04:46:05 PDT 2020


Author: Raphael Isemann
Date: 2020-09-04T13:45:42+02:00
New Revision: 101f37a1b330e3f0ae57762db47bba28f72cf50d

URL: https://github.com/llvm/llvm-project/commit/101f37a1b330e3f0ae57762db47bba28f72cf50d
DIFF: https://github.com/llvm/llvm-project/commit/101f37a1b330e3f0ae57762db47bba28f72cf50d.diff

LOG: [lldb][NFC] Rewrite CPP11EnumTypes test to make it faster

TestCPP11EnumTypes is one of the most expensive tests on my system and takes
around 35 seconds to run. A relatively large amount of that time is actually
doing CPU intensive work it seems (and not waiting on timeouts like other
slow tests).

The main issue is that this test repeatedly compiles the same source files
with different compiler defines. The test is also including standard library
headers, so it will also build all system modules with the gmodules debug
info variant. This leads to the problem that this test ends up compiling all
system Clang modules 8 times (one for each subtest with a unique define). As
the system modules are quite large, this causes that this test spends most
of its runtime just recompiling all system modules on macOS.

There is also the small issue that this test is starting and start-stopping
the test process a few hundred times.

This rewrites the test to instead just use a macro to instantiate all the
enum types in a single source and uses global variables to test the values
(which means there is no more need to continue/stop or even start a process).

I kept running all the debug info variants (event though it doesn't seem really
relevant) to keep this as NFC as possible.

This reduced the test runtime by around 1.5 seconds on my system (or in relative
numbers, the runtime of this test decreases by 95%).

Added: 
    

Modified: 
    lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
    lldb/test/API/lang/cpp/enum_types/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py b/lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
index c58f700039eb..d40eee0cb1b0 100644
--- a/lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
+++ b/lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
@@ -1,7 +1,5 @@
 """Look up enum type information and check for correct display."""
 
-
-
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
@@ -12,145 +10,45 @@ class CPP11EnumTypesTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
 
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_int8_t(self):
-        """Test C++11 enumeration class types as int8_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int8_t"'})
-        self.image_lookup_for_enum_type(True)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_int16_t(self):
-        """Test C++11 enumeration class types as int16_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int16_t"'})
-        self.image_lookup_for_enum_type(True)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_int32_t(self):
-        """Test C++11 enumeration class types as int32_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int32_t"'})
-        self.image_lookup_for_enum_type(True)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_int64_t(self):
-        """Test C++11 enumeration class types as int64_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int64_t"'})
-        self.image_lookup_for_enum_type(True)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_uint8_t(self):
-        """Test C++11 enumeration class types as uint8_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint8_t"'})
-        self.image_lookup_for_enum_type(False)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_uint16_t(self):
-        """Test C++11 enumeration class types as uint16_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint16_t"'})
-        self.image_lookup_for_enum_type(False)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_uint32_t(self):
-        """Test C++11 enumeration class types as uint32_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint32_t"'})
-        self.image_lookup_for_enum_type(False)
-
-    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
-    @skipIf(dwarf_version=['<', '4'])
-    def test_uint64_t(self):
-        """Test C++11 enumeration class types as uint64_t types."""
-        self.build(
-            dictionary={
-                'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint64_t"'})
-        self.image_lookup_for_enum_type(False)
-
-    def setUp(self):
-        # Call super's setUp().
-        TestBase.setUp(self)
-        # Find the line number to break inside main().
-        self.line = line_number('main.cpp', '// Set break point at this line.')
-
-    def image_lookup_for_enum_type(self, is_signed):
-        """Test C++11 enumeration class types."""
-        exe = self.getBuildArtifact("a.out")
-        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
-
-        # Break inside the main.
-        bkpt_id = lldbutil.run_break_set_by_file_and_line(
-            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
-
-        self.runCmd("run", RUN_SUCCEEDED)
-
-        # The stop reason of the thread should be breakpoint.
-        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-                    substrs=['stopped',
-                             'stop reason = breakpoint'])
-
-        # The breakpoint should have a hit count of 1.
-        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
-                    substrs=[' resolved, hit count = 1'])
-
-        # Look up information about the 'DayType' enum type.
-        # Check for correct display.
-        self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY,
-                    patterns=['enum( struct| class) DayType {'],
-                    substrs=['Monday',
-                             'Tuesday',
-                             'Wednesday',
-                             'Thursday',
-                             'Friday',
-                             'Saturday',
-                             'Sunday',
-                             'kNumDays',
-                             '}'])
-
-        if is_signed:
-            enum_values = ['-4',
-                           'Monday',
-                           'Tuesday',
-                           'Wednesday',
-                           'Thursday',
-                           'Friday',
-                           'Saturday',
-                           'Sunday',
-                           'kNumDays',
-                           '5']
+    def check_enum(self, suffix):
+        """
+        :param suffix The suffix of the enum type name (enum_<suffix>) that
+                      should be checked.
+        :param test_values A list of integet values that shouldn't be converted
+                           to any valid enum case.
+        """
+        enum_name = "enum_" + suffix
+        unsigned = suffix.startswith("u")
+
+        self.expect("image lookup -t " + enum_name,
+                    patterns=["enum( struct| class) " + enum_name + " {"],
+                    substrs=["Case1",
+                             "Case2",
+                             "Case3"])
+        # Test each case in the enum.
+        self.expect_expr("var1_" + suffix, result_type=enum_name, result_value="Case1")
+        self.expect_expr("var2_" + suffix, result_type=enum_name, result_value="Case2")
+        self.expect_expr("var3_" + suffix, result_type=enum_name, result_value="Case3")
+
+        if unsigned:
+            self.expect_expr("var_below_" + suffix, result_type=enum_name, result_value="199")
+            self.expect_expr("var_above_" + suffix, result_type=enum_name, result_value="203")
         else:
-            enum_values = ['199',
-                           'Monday',
-                           'Tuesday',
-                           'Wednesday',
-                           'Thursday',
-                           'Friday',
-                           'Saturday',
-                           'Sunday',
-                           'kNumDays',
-                           '208']
-
-        bkpt = self.target().FindBreakpointByID(bkpt_id)
-        for enum_value in enum_values:
-            self.expect(
-                "frame variable day",
-                'check for valid enumeration value',
-                substrs=[enum_value])
-            lldbutil.continue_to_breakpoint(self.process(), bkpt)
+            self.expect_expr("var_below_" + suffix, result_type=enum_name, result_value="-3")
+            self.expect_expr("var_above_" + suffix, result_type=enum_name, result_value="1")
+
+    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527')
+    @skipIf(dwarf_version=['<', '4'])
+    def test(self):
+        self.build()
+        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+        self.check_enum("uc")
+        self.check_enum("c")
+        self.check_enum("us")
+        self.check_enum("s")
+        self.check_enum("ui")
+        self.check_enum("i")
+        self.check_enum("ul")
+        self.check_enum("l")
+        self.check_enum("ull")
+        self.check_enum("ll")

diff  --git a/lldb/test/API/lang/cpp/enum_types/main.cpp b/lldb/test/API/lang/cpp/enum_types/main.cpp
index d7d428a24432..be895208c7d4 100644
--- a/lldb/test/API/lang/cpp/enum_types/main.cpp
+++ b/lldb/test/API/lang/cpp/enum_types/main.cpp
@@ -1,41 +1,28 @@
-#include <stdio.h>
-#include <stdint.h>
+#define DEFINE_UNSIGNED_ENUM(suffix, enum_type)                                \
+  enum class enum_##suffix : enum_type{Case1 = 200, Case2, Case3};             \
+  enum_##suffix var1_##suffix = enum_##suffix ::Case1;                         \
+  enum_##suffix var2_##suffix = enum_##suffix ::Case2;                         \
+  enum_##suffix var3_##suffix = enum_##suffix ::Case3;                         \
+  enum_##suffix var_below_##suffix = static_cast<enum_##suffix>(199);          \
+  enum_##suffix var_above_##suffix = static_cast<enum_##suffix>(203);
 
+#define DEFINE_SIGNED_ENUM(suffix, enum_type)                                  \
+  enum class enum_##suffix : enum_type{Case1 = -2, Case2, Case3};              \
+  enum_##suffix var1_##suffix = enum_##suffix ::Case1;                         \
+  enum_##suffix var2_##suffix = enum_##suffix ::Case2;                         \
+  enum_##suffix var3_##suffix = enum_##suffix ::Case3;                         \
+  enum_##suffix var_below_##suffix = static_cast<enum_##suffix>(-3);           \
+  enum_##suffix var_above_##suffix = static_cast<enum_##suffix>(1);
 
-int main (int argc, char const *argv[])
-{
-#ifdef SIGNED_ENUM_CLASS_TYPE
-    typedef SIGNED_ENUM_CLASS_TYPE enum_integer_t;
-    enum class DayType : enum_integer_t {
-        Monday = -3,
-        Tuesday,
-        Wednesday,
-        Thursday,
-        Friday,
-        Saturday,
-        Sunday,
-        kNumDays
-    };
-    enum_integer_t day_value;
-#else
-    typedef UNSIGNED_ENUM_CLASS_TYPE enum_integer_t;
-    enum class DayType : enum_integer_t {
-        Monday = 200,
-        Tuesday,
-        Wednesday,
-        Thursday,
-        Friday,
-        Saturday,
-        Sunday,
-        kNumDays
-    };
-    enum_integer_t day_value;
-#endif
+DEFINE_UNSIGNED_ENUM(uc, unsigned char)
+DEFINE_SIGNED_ENUM(c, signed char)
+DEFINE_UNSIGNED_ENUM(us, unsigned short int)
+DEFINE_SIGNED_ENUM(s, signed short int)
+DEFINE_UNSIGNED_ENUM(ui, unsigned int)
+DEFINE_SIGNED_ENUM(i, signed int)
+DEFINE_UNSIGNED_ENUM(ul, unsigned long)
+DEFINE_SIGNED_ENUM(l, signed long)
+DEFINE_UNSIGNED_ENUM(ull, unsigned long long)
+DEFINE_SIGNED_ENUM(ll, signed long long)
 
-    for (day_value = (enum_integer_t)DayType::Monday - 1; day_value <= (enum_integer_t)DayType::kNumDays + 1; ++day_value)
-    {
-        DayType day = (DayType)day_value;
-        printf("day as int is %i\n", (int)day); // Set break point at this line.
-    }
-    return 0; // Break here for char tests
-}
+int main(int argc, char const *argv[]) { return 0; }


        


More information about the lldb-commits mailing list