[PATCH] D87187: [Driver] Perform Linux distribution detection just once

Dmitry Antipov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 5 04:45:48 PDT 2020


dmantipov created this revision.
dmantipov added reviewers: mgorny, aganea.
dmantipov added a project: clang.
Herald added a subscriber: cfe-commits.
dmantipov requested review of this revision.

When running regular ('clang++ foo.cc') native compilation on Linux target in a typical configuration, an attempt to detect distribution type is performed 4 times at least:

- during an attempt to detect CUDA installation in clang::driver::CudaInstallationDetector::CudaInstallationDetector();

- during an instantiation of Linux-specific toolchain driver (clang::driver::toolchains::Linux::Linux());

- when special handling of '-faddrsig' is performed in  clang::driver::tools::Clang::ConstructJob();

- finally when constructing a linker job in  clang::driver::toolchains::Linux::getDynamicLinker().

Since distribution detection involves VFS, filesystem I/O and even parsing of file(s) contents, it looks desirable to cache the result and perform the whole procedure just once.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87187

Files:
  clang/include/clang/Driver/Distro.h
  clang/lib/Driver/Distro.cpp


Index: clang/lib/Driver/Distro.cpp
===================================================================
--- clang/lib/Driver/Distro.cpp
+++ clang/lib/Driver/Distro.cpp
@@ -21,20 +21,10 @@
 
 static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS,
                                        const llvm::Triple &TargetOrHost) {
-  // If we don't target Linux, no need to check the distro. This saves a few
-  // OS calls.
-  if (!TargetOrHost.isOSLinux())
-    return Distro::UnknownDistro;
-
-  // If the host is not running Linux, and we're backed by a real file system,
-  // no need to check the distro. This is the case where someone is
-  // cross-compiling from BSD or Windows to Linux, and it would be meaningless
-  // to try to figure out the "distro" of the non-Linux host.
-  IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS =
-      llvm::vfs::getRealFileSystem();
-  llvm::Triple HostTriple(llvm::sys::getProcessTriple());
-  if (!HostTriple.isOSLinux() && &VFS == RealFS.get())
-    return Distro::UnknownDistro;
+  // We're definitely on Linux, so start looking for the filesystem artifacts.
+  // TODO: adjust this to match modern freedesktop.org's compilant system
+  // with /etc/os-release and/or /usr/lib/os-release. For the details,
+  // see https://www.freedesktop.org/software/systemd/man/os-release.html.
 
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
       VFS.getBufferForFile("/etc/lsb-release");
@@ -168,5 +158,36 @@
   return Distro::UnknownDistro;
 }
 
+static Distro::DistroType GetDistro(llvm::vfs::FileSystem &VFS,
+                                    const llvm::Triple &TargetOrHost) {
+  static Distro::DistroType Type = Distro::UninitializedDistro;
+
+  // If we don't target Linux, no need to check the distro. This saves a few
+  // OS calls.
+  if (!TargetOrHost.isOSLinux())
+    return Distro::UnknownDistro;
+
+  // If we perform the detection already, return the result. This saves a few
+  // more OS calls assuming there was no underlying on-the fly distro change.
+  if (Type != Distro::UninitializedDistro)
+    return Type;
+
+  // If the host is not running Linux, and we're backed by a real file system,
+  // no need to check the distro. This is the case where someone is
+  // cross-compiling from BSD or Windows to Linux, and it would be meaningless
+  // to try to figure out the "distro" of the non-Linux host.
+  IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS =
+      llvm::vfs::getRealFileSystem();
+  llvm::Triple HostTriple(llvm::sys::getProcessTriple());
+
+  if (!HostTriple.isOSLinux() && &VFS == RealFS.get())
+    Type = Distro::UnknownDistro;
+  else
+    // Perform the detection and save the result.
+    Type = DetectDistro(VFS, TargetOrHost);
+
+  return Type;
+}
+
 Distro::Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost)
-    : DistroVal(DetectDistro(VFS, TargetOrHost)) {}
+    : DistroVal(GetDistro(VFS, TargetOrHost)) {}
Index: clang/include/clang/Driver/Distro.h
===================================================================
--- clang/include/clang/Driver/Distro.h
+++ clang/include/clang/Driver/Distro.h
@@ -23,6 +23,8 @@
 class Distro {
 public:
   enum DistroType {
+    // Special value means that no detection was performed yet.
+    UninitializedDistro = -1,
     // NB: Releases of a particular Linux distro should be kept together
     // in this enum, because some tests are done by integer comparison against
     // the first and last known member in the family, e.g. IsRedHat().


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87187.290079.patch
Type: text/x-patch
Size: 3521 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200905/7c8c3cab/attachment.bin>


More information about the cfe-commits mailing list