From: Simon Atanasyan Date: Tue, 4 Mar 2014 18:37:28 +0000 (+0000) Subject: [Mips] Check all MIPS toolchains to find the one that best meets command X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7beeda8f88e18a099e26908738b33f2162004d8;p=clang [Mips] 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 O32 ABI only. Patch reviewed by Jonathan Roelofs, David Majnemer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202873 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 9d7e533c06..83ba05b47f 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1669,6 +1669,9 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( .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 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( .FilterOut("/mips32/64") .FilterOut("^/64") .FilterOut("/mips16/64") - .Maybe(LittleEndian) + .Either(BigEndian, LittleEndian) .Maybe(SoftFloat) .Maybe(FP64) .Maybe(Nan2008) @@ -1747,6 +1750,9 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( 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 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( .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 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( .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,31 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( 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 first. + // Then select the first toolchains matches command line flags. + MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs, + &CSMipsMultilibs }; + std::sort( + std::begin(candidates), std::end(candidates), + [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); }); + for (const 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( diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/lib/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/lib/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/lib/mips-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/lib/mips-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/lib/mipsel-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/lib/mipsel-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/backward/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/backward/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mips-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mips-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mipsel-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mipsel-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mips-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mips-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mipsel-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mipsel-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mips-linux-gnu/4.7/crtbegin.o b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mips-linux-gnu/4.7/crtbegin.o new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mipsel-linux-gnu/4.7/crtbegin.o b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mipsel-linux-gnu/4.7/crtbegin.o new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mips-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mips-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mipsel-linux-gnu/.keep b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mipsel-linux-gnu/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/mips-reduced-toolchain.cpp b/test/Driver/mips-reduced-toolchain.cpp new file mode 100644 index 0000000000..fe7ed8ae04 --- /dev/null +++ b/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"