From dea079e4f5131546be66c209668448f8e9a5a0da Mon Sep 17 00:00:00 2001 From: Pirama Arumuga Nainar Date: Mon, 9 Sep 2019 18:31:41 +0000 Subject: [PATCH] [Driver] Add -static-openmp driver option Summary: For Gnu, FreeBSD and NetBSD, this option forces linking with the static OpenMP host runtime (similar to -static-libgcc and -static-libstdcxx). Android's NDK will start the shared OpenMP runtime in addition to the static libomp. In this scenario, the linker will prefer to use the shared library by default. Add this option to enable linking with the static libomp. Reviewers: Hahnfeld, danalbert, srhines, joerg, jdoerfert Subscribers: guansong, cfe-commits Tags: #clang Fixes https://github.com/android-ndk/ndk/issues/1028 Differential Revision: https://reviews.llvm.org/D67200 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@371437 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Options.td | 2 ++ lib/Driver/ToolChains/CommonArgs.cpp | 27 ++++++++++++++++-------- lib/Driver/ToolChains/CommonArgs.h | 1 + lib/Driver/ToolChains/FreeBSD.cpp | 6 +++++- lib/Driver/ToolChains/Gnu.cpp | 6 +++++- lib/Driver/ToolChains/NetBSD.cpp | 6 +++++- test/Driver/fopenmp.c | 31 ++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 12 deletions(-) diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index f8462a77c9..01c0cd2db6 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1616,6 +1616,8 @@ def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Gr Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group, Flags<[NoArgumentUnused, HelpHidden]>; +def static_openmp: Flag<["-"], "static-openmp">, + HelpText<"Use the static host OpenMP runtime while linking.">; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group; def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group; def fno_escaping_block_tail_calls : Flag<["-"], "fno-escaping-block-tail-calls">, Group, Flags<[CC1Option]>; diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index 523d7d9087..e07b052487 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -500,30 +500,39 @@ void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args, } bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, - const ArgList &Args, bool IsOffloadingHost, - bool GompNeedsRT) { + const ArgList &Args, bool ForceStaticHostRuntime, + bool IsOffloadingHost, bool GompNeedsRT) { if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, options::OPT_fno_openmp, false)) return false; - switch (TC.getDriver().getOpenMPRuntime(Args)) { + Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args); + + if (RTKind == Driver::OMPRT_Unknown) + // Already diagnosed. + return false; + + if (ForceStaticHostRuntime) + CmdArgs.push_back("-Bstatic"); + + switch (RTKind) { case Driver::OMPRT_OMP: CmdArgs.push_back("-lomp"); break; case Driver::OMPRT_GOMP: CmdArgs.push_back("-lgomp"); - - if (GompNeedsRT) - CmdArgs.push_back("-lrt"); break; case Driver::OMPRT_IOMP5: CmdArgs.push_back("-liomp5"); break; - case Driver::OMPRT_Unknown: - // Already diagnosed. - return false; } + if (ForceStaticHostRuntime) + CmdArgs.push_back("-Bdynamic"); + + if (RTKind == Driver::OMPRT_GOMP && GompNeedsRT) + CmdArgs.push_back("-lrt"); + if (IsOffloadingHost) CmdArgs.push_back("-lomptarget"); diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h index 9a311708f3..1aff07ab8f 100644 --- a/lib/Driver/ToolChains/CommonArgs.h +++ b/lib/Driver/ToolChains/CommonArgs.h @@ -84,6 +84,7 @@ void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args, /// Returns true, if an OpenMP runtime has been added. bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, const llvm::opt::ArgList &Args, + bool ForceStaticHostRuntime = false, bool IsOffloadingHost = false, bool GompNeedsRT = false); llvm::opt::Arg *getLastProfileUseArg(const llvm::opt::ArgList &Args); diff --git a/lib/Driver/ToolChains/FreeBSD.cpp b/lib/Driver/ToolChains/FreeBSD.cpp index 8b7f369338..7c891a24ba 100644 --- a/lib/Driver/ToolChains/FreeBSD.cpp +++ b/lib/Driver/ToolChains/FreeBSD.cpp @@ -270,7 +270,11 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - addOpenMPRuntime(CmdArgs, ToolChain, Args); + // Use the static OpenMP runtime with -static-openmp + bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && + !Args.hasArg(options::OPT_static); + addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index d4149ea201..71ed529b79 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -555,9 +555,13 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, bool WantPthread = Args.hasArg(options::OPT_pthread) || Args.hasArg(options::OPT_pthreads); + // Use the static OpenMP runtime with -static-openmp + bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && + !Args.hasArg(options::OPT_static); + // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that // require librt. Most modern Linux platforms do, but some may not. - if (addOpenMPRuntime(CmdArgs, ToolChain, Args, + if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP, JA.isHostOffloading(Action::OFK_OpenMP), /* GompNeedsRT= */ true)) // OpenMP runtimes implies pthreads when using the GNU toolchain. diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp index 782dd622b7..af6720d159 100644 --- a/lib/Driver/ToolChains/NetBSD.cpp +++ b/lib/Driver/ToolChains/NetBSD.cpp @@ -289,7 +289,11 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - addOpenMPRuntime(CmdArgs, getToolChain(), Args); + // Use the static OpenMP runtime with -static-openmp + bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && + !Args.hasArg(options::OPT_static); + addOpenMPRuntime(CmdArgs, getToolChain(), Args, StaticOpenMP); + if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); diff --git a/test/Driver/fopenmp.c b/test/Driver/fopenmp.c index e505252ebc..6a5b643056 100644 --- a/test/Driver/fopenmp.c +++ b/test/Driver/fopenmp.c @@ -31,6 +31,11 @@ // RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-RT // RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // +// RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-RT +// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 @@ -47,6 +52,11 @@ // RUN: %clang -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT // RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // +// RUN: %clang -target x86_64-freebsd -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang -target x86_64-freebsd -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 @@ -55,6 +65,11 @@ // RUN: %clang -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT // RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // +// RUN: %clang -target x86_64-netbsd -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 @@ -93,6 +108,22 @@ // CHECK-NO-IOMP5MD: "{{.*}}ld{{(.exe)?}}" // CHECK-NO-IOMP5MD-NOT: "-liomp5md" // +// CHECK-LD-STATIC-OMP: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" +// +// CHECK-LD-STATIC-GOMP: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-STATIC-GOMP: "-Bstatic" "-lgomp" "-Bdynamic" +// CHECK-LD-STATIC-GOMP-RT: "-lrt" +// CHECK-LD-STATIC-NO-GOMP-RT-NOT: "-lrt" +// +// CHECK-LD-STATIC-IOMP5: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-STATIC-IOMP5: "-Bstatic" "-liomp5" "-Bdynamic" +// +// CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC: "{{.*}}ld{{(.exe)?}}" +// For x86 Gnu, the driver passes -static, while NetBSD and FreeBSD pass -Bstatic +// CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC: "-{{B?}}static" {{.*}} "-liomp5" +// CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC-NOT: "-Bdynamic" +// // We'd like to check that the default is sane, but until we have the ability // to *always* semantically analyze OpenMP without always generating runtime // calls (in the event of an unsupported runtime), we don't have a good way to -- 2.40.0