[PATCH] Fix MIPS toolchain selection heuristics in case of reduced toolchain directories tree

Simon Atanasyan simon at atanasyan.com
Sun Mar 2 01:36:13 PST 2014


Hi jroelofs,

Check all MIPS toolchains to find the one that best meets command line arguments and directories tree. The old toolchain selection heuristics worked incorrectly when user has a reduced MIPS toolchain supports the only O32 ABI.

http://llvm-reviews.chandlerc.com/D2911

Files:
  lib/Driver/ToolChains.cpp
  test/Driver/Inputs/debian_reduced_mips_tree/lib/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/lib/mips-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/lib/mipsel-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/backward/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mips-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mipsel-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mips-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mipsel-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mips-linux-gnu/4.7/crtbegin.o
  test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mipsel-linux-gnu/4.7/crtbegin.o
  test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mips-linux-gnu/.keep
  test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mipsel-linux-gnu/.keep
  test/Driver/mips-reduced-toolchain.cpp

Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -1669,6 +1669,9 @@
       .includeSuffix("/64")
       .flag("+mabi=64").flag("-mabi=n32").flag("-m32");
 
+    Multilib BigEndian = Multilib()
+      .flag("+EB").flag("-EL");
+
     Multilib LittleEndian = Multilib()
       .gccSuffix("/el")
       .osSuffix("/el")
@@ -1705,7 +1708,7 @@
       .FilterOut("/mips32/64")
       .FilterOut("^/64")
       .FilterOut("/mips16/64")
-      .Maybe(LittleEndian)
+      .Either(BigEndian, LittleEndian)
       .Maybe(SoftFloat)
       .Maybe(FP64)
       .Maybe(Nan2008)
@@ -1747,6 +1750,9 @@
     Multilib DefaultFloat = Multilib()
       .flag("-msoft-float").flag("-mnan=2008");
 
+    Multilib BigEndian = Multilib()
+      .flag("+EB").flag("-EL");
+
     Multilib LittleEndian = Multilib()
       .gccSuffix("/el")
       .osSuffix("/el")
@@ -1764,7 +1770,7 @@
       .Either(SoftFloat, Nan2008, DefaultFloat)
       .FilterOut("/micromips/nan2008")
       .FilterOut("/mips16/nan2008")
-      .Maybe(LittleEndian)
+      .Either(BigEndian, LittleEndian)
       .Maybe(MAbi64)
       .FilterOut("/mips16.*/64")
       .FilterOut("/micromips.*/64")
@@ -1795,21 +1801,6 @@
       .FilterOut(NonExistent);
   }
 
-  Multilibs.clear();
-
-  // Decide which MultilibSet matches best for the given path
-  // (we do this rather than combining them all because there is a
-  //  a bit of overlap in the directories that each specifies)
-  if (TargetTriple.getEnvironment() == llvm::Triple::Android)
-    Multilibs.combineWith(AndroidMipsMultilibs);
-  else if (DebianMipsMultilibs.size() == 3) {
-    Multilibs.combineWith(DebianMipsMultilibs);
-    BiarchSibling = Multilib();
-  } else if (FSFMipsMultilibs.size() > CSMipsMultilibs.size())
-    Multilibs.combineWith(FSFMipsMultilibs);
-  else
-    Multilibs.combineWith(CSMipsMultilibs);
-
   llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
 
   Multilib::flags_list Flags;
@@ -1835,7 +1826,32 @@
   addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
   addMultilibFlag(isMipsEB(TargetArch), "EB", Flags);
 
-  return Multilibs.select(Flags, SelectedMultilib);
+  if (TargetTriple.getEnvironment() == llvm::Triple::Android) {
+    // Select Android toolchain. It's the only choice in that case.
+    Multilibs.clear();
+    Multilibs.combineWith(AndroidMipsMultilibs);
+    return Multilibs.select(Flags, SelectedMultilib);
+  }
+
+  // Sort candidates. Toolchain that best meets the directories goes firts.
+  // Then select the first toolchains matches command line flags.
+  std::vector<MultilibSet *> candidates = { &DebianMipsMultilibs,
+                                            &FSFMipsMultilibs,
+                                            &CSMipsMultilibs };
+  std::sort(
+      std::begin(candidates), std::end(candidates),
+      [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); });
+  for (auto candidate : candidates) {
+    Multilibs.clear();
+    Multilibs.combineWith(*candidate);
+    if (Multilibs.select(Flags, SelectedMultilib)) {
+      if (candidate == &DebianMipsMultilibs)
+        BiarchSibling = Multilib();
+      return true;
+    }
+  }
+
+  return false;
 }
 
 bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs(
Index: test/Driver/mips-reduced-toolchain.cpp
===================================================================
--- /dev/null
+++ test/Driver/mips-reduced-toolchain.cpp
@@ -0,0 +1,28 @@
+// Check frontend and linker invocations on reduced Debian MIPS toolchain.
+// This toolchain icludes O32 ABI only.
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/debian_reduced_mips_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-MIPS %s
+// CHECK-DEBIAN-MIPS: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-MIPS: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.7{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../../mips-linux-gnu"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/mips-linux-gnu"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../.."
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/debian_reduced_mips_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-MIPSEL %s
+// CHECK-DEBIAN-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-MIPSEL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.7{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../../mipsel-linux-gnu"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/mipsel-linux-gnu"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../.."
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2911.1.patch
Type: text/x-patch
Size: 5238 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140302/18a4d0bd/attachment.bin>


More information about the cfe-commits mailing list