[llvm] bcb8ef2 - abtest.py: support bisection based on a response file

Yuanfang Chen via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 8 09:47:03 PDT 2021


Author: Yuanfang Chen
Date: 2021-04-08T09:46:01-07:00
New Revision: bcb8ef2d5a8ba4cea44bb39a856ba3ef88c8c2f7

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

LOG: abtest.py: support bisection based on a response file

Also makes LINK_TEST customizable from commandline with `--test` option.

Added: 
    

Modified: 
    llvm/utils/abtest.py

Removed: 
    


################################################################################
diff  --git a/llvm/utils/abtest.py b/llvm/utils/abtest.py
index 69a86f6482d1..4ca3ca4f730e 100755
--- a/llvm/utils/abtest.py
+++ b/llvm/utils/abtest.py
@@ -7,6 +7,10 @@
 # list of files which should be linked together and result tested. "link_test"
 # should returns with exitcode 0 if the linking and testing succeeded.
 #
+# If a response file is provided, only the object files that are listed in the
+# file are inspected. In addition, the "link_test" is called with a temporary
+# response file representing one iteration of bisection.
+#
 # abtest.py operates by taking all files from the "before" directory and
 # in each step replacing one of them with a file from the "bad" directory.
 #
@@ -41,9 +45,10 @@
 import os
 import subprocess
 import sys
+import tempfile
 
-
-LINKTEST = "./link_test"
+# Specify LINKTEST via `--test`. Default value is './link_test'.
+LINKTEST = ""
 ESCAPE = "\033[%sm"
 BOLD = ESCAPE % "1"
 RED = ESCAPE % "31"
@@ -234,22 +239,42 @@ def testrun(files):
         return True
 
 
-def prepare_files(gooddir, baddir):
-    files_a = find(gooddir, "*")
-    files_b = find(baddir, "*")
+def prepare_files(gooddir, baddir, rspfile):
+    files_a = []
+    files_b = []
+
+    if rspfile is not None:
+        def get_basename(name):
+            # remove prefix
+            if name.startswith(gooddir):
+                return name[len(gooddir):]
+            if name.startswith(baddir):
+                return name[len(baddir):]
+            assert False, ""
+
+        with open(rspfile, "r") as rf:
+            for line in rf.read().splitlines():
+                for obj in line.split():
+                    assert not os.path.isabs(obj), "TODO: support abs path"
+                    files_a.append(gooddir + "/" + obj)
+                    files_b.append(baddir + "/" + obj)
+    else:
+        get_basename = lambda name: os.path.basename(name)
+        files_a = find(gooddir, "*")
+        files_b = find(baddir, "*")
 
-    basenames_a = set(map(os.path.basename, files_a))
-    basenames_b = set(map(os.path.basename, files_b))
+    basenames_a = set(map(get_basename, files_a))
+    basenames_b = set(map(get_basename, files_b))
 
     for name in files_b:
-        basename = os.path.basename(name)
+        basename = get_basename(name)
         if basename not in basenames_a:
             warn("There is no corresponding file to '%s' in %s" %
                  (name, gooddir))
     choices = []
     skipped = []
     for name in files_a:
-        basename = os.path.basename(name)
+        basename = get_basename(name)
         if basename not in basenames_b:
             warn("There is no corresponding file to '%s' in %s" %
                  (name, baddir))
@@ -271,13 +296,25 @@ def perform_test(picks):
         # Note that we iterate over files_a so we don't change the order
         # (cannot use `picks` as it is a dictionary without order)
         for x in files_a:
-            basename = os.path.basename(x)
+            basename = get_basename(x)
             picked = picks.get(basename)
             if picked is None:
                 assert basename in skipped
                 files.append(x)
             else:
                 files.append(picked)
+
+        # If response file is used, create a temporary response file for the
+        # picked files.
+        if rspfile is not None:
+            with tempfile.NamedTemporaryFile('w', suffix='.rsp',
+                                             delete=False) as tf:
+                tf.write(" ".join(files))
+                tf.flush()
+            ret = testrun([tf.name])
+            os.remove(tf.name)
+            return ret
+
         return testrun(files)
 
     return perform_test, choices
@@ -332,6 +369,8 @@ def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('--a', dest='dir_a', default='before')
     parser.add_argument('--b', dest='dir_b', default='after')
+    parser.add_argument('--rsp', default=None)
+    parser.add_argument('--test', default='./link_test')
     parser.add_argument('--insane', help='Skip sanity check',
                         action='store_true')
     parser.add_argument('--seq',
@@ -342,6 +381,9 @@ def main():
 
     gooddir = config.dir_a
     baddir = config.dir_b
+    rspfile = config.rsp
+    global LINKTEST
+    LINKTEST = config.test
 
     # Preparation phase: Creates a dictionary mapping names to a list of two
     # choices each. The bisection algorithm will pick one choice for each name
@@ -352,7 +394,7 @@ def main():
         perform_test, choices = prepare_functions(config.file, gooddir,
                                                   goodfile, badfile)
     else:
-        perform_test, choices = prepare_files(gooddir, baddir)
+        perform_test, choices = prepare_files(gooddir, baddir, rspfile)
 
     info("%d bisection choices" % len(choices))
 


        


More information about the llvm-commits mailing list