From 55b58df36e758826d6b27598ca37c211b8fecf8a Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 12 Dec 2018 14:52:27 +0000 Subject: [PATCH] [CUDA][OPENMP][NVPTX]Improve logic of the debug info support. Summary: Added support for the -gline-directives-only option + fixed logic of the debug info for CUDA devices. If optimization level is O0, then options --[no-]cuda-noopt-device-debug do not affect the debug info level. If the optimization level is >O0, debug info options are used + --no-cuda-noopt-device-debug is used or no --cuda-noopt-device-debug is used, the optimization level for the device code is kept and the emission of the debug directives is used. If the opt level is > O0, debug info is requested + --cuda-noopt-device-debug option is used, the optimization is disabled for the device code + required debug info is emitted. Reviewers: tra, echristo Subscribers: aprantl, guansong, JDevlieghere, cfe-commits Differential Revision: https://reviews.llvm.org/D51554 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348930 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/ToolChain.h | 5 ++ lib/Driver/ToolChains/Clang.cpp | 3 ++ lib/Driver/ToolChains/Cuda.cpp | 79 +++++++++++++++++++++----------- lib/Driver/ToolChains/Cuda.h | 2 + test/Driver/cuda-dwarf-2.cu | 30 ++++++++---- test/Driver/openmp-offload-gpu.c | 31 +++++++++---- 6 files changed, 104 insertions(+), 46 deletions(-) diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 73fd914ad1..43a82a7b43 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H #define LLVM_CLANG_DRIVER_TOOLCHAIN_H +#include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/DebugInfoOptions.h" @@ -435,6 +436,10 @@ public: return true; } + /// Adjust debug information kind considering all passed options. + virtual void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, + const llvm::opt::ArgList &Args) const {} + /// GetExceptionModel - Return the tool chain exception model. virtual llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const; diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index eaaa1bbff2..360397cf5b 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -3233,6 +3233,9 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, } } + // Adjust the debug info kind for the given toolchain. + TC.adjustDebugInfoKind(DebugInfoKind, Args); + RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion, DebuggerTuning); diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp index a8363b2f95..57b8d4340e 100644 --- a/lib/Driver/ToolChains/Cuda.cpp +++ b/lib/Driver/ToolChains/Cuda.cpp @@ -278,32 +278,44 @@ void CudaInstallationDetector::print(raw_ostream &OS) const { } namespace { - /// Debug info kind. -enum DebugInfoKind { - NoDebug, /// No debug info. - LineTableOnly, /// Line tables only. - FullDebug /// Full debug info. +/// Debug info level for the NVPTX devices. We may need to emit different debug +/// info level for the host and for the device itselfi. This type controls +/// emission of the debug info for the devices. It either prohibits disable info +/// emission completely, or emits debug directives only, or emits same debug +/// info as for the host. +enum DeviceDebugInfoLevel { + DisableDebugInfo, /// Do not emit debug info for the devices. + DebugDirectivesOnly, /// Emit only debug directives. + EmitSameDebugInfoAsHost, /// Use the same debug info level just like for the + /// host. }; } // anonymous namespace -static DebugInfoKind mustEmitDebugInfo(const ArgList &Args) { - Arg *A = Args.getLastArg(options::OPT_O_Group); - if (Args.hasFlag(options::OPT_cuda_noopt_device_debug, - options::OPT_no_cuda_noopt_device_debug, - !A || A->getOption().matches(options::OPT_O0))) { - if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { - const Option &Opt = A->getOption(); - if (Opt.matches(options::OPT_gN_Group)) { - if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0)) - return NoDebug; - if (Opt.matches(options::OPT_gline_tables_only) || - Opt.matches(options::OPT_ggdb1)) - return LineTableOnly; - } - return FullDebug; +/// Define debug info level for the NVPTX devices. If the debug info for both +/// the host and device are disabled (-g0/-ggdb0 or no debug options at all). If +/// only debug directives are requested for the both host and device +/// (-gline-directvies-only), or the debug info only for the device is disabled +/// (optimization is on and --cuda-noopt-device-debug was not specified), the +/// debug directves only must be emitted for the device. Otherwise, use the same +/// debug info level just like for the host (with the limitations of only +/// supported DWARF2 standard). +static DeviceDebugInfoLevel mustEmitDebugInfo(const ArgList &Args) { + const Arg *A = Args.getLastArg(options::OPT_O_Group); + bool IsDebugEnabled = !A || A->getOption().matches(options::OPT_O0) || + Args.hasFlag(options::OPT_cuda_noopt_device_debug, + options::OPT_no_cuda_noopt_device_debug, + /*Default=*/false); + if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { + const Option &Opt = A->getOption(); + if (Opt.matches(options::OPT_gN_Group)) { + if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0)) + return DisableDebugInfo; + if (Opt.matches(options::OPT_gline_directives_only)) + return DebugDirectivesOnly; } + return IsDebugEnabled ? EmitSameDebugInfoAsHost : DebugDirectivesOnly; } - return NoDebug; + return DisableDebugInfo; } void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, @@ -337,8 +349,8 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList CmdArgs; CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32"); - DebugInfoKind DIKind = mustEmitDebugInfo(Args); - if (DIKind == FullDebug) { + DeviceDebugInfoLevel DIKind = mustEmitDebugInfo(Args); + if (DIKind == EmitSameDebugInfoAsHost) { // ptxas does not accept -g option if optimization is enabled, so // we ignore the compiler's -O* options if we want debug info. CmdArgs.push_back("-g"); @@ -374,7 +386,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, // to no optimizations, but ptxas's default is -O3. CmdArgs.push_back("-O0"); } - if (DIKind == LineTableOnly) + if (DIKind == DebugDirectivesOnly) CmdArgs.push_back("-lineinfo"); // Pass -v to ptxas if it was passed to the driver. @@ -445,7 +457,7 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32"); CmdArgs.push_back(Args.MakeArgString("--create")); CmdArgs.push_back(Args.MakeArgString(Output.getFilename())); - if (mustEmitDebugInfo(Args) == FullDebug) + if (mustEmitDebugInfo(Args) == EmitSameDebugInfoAsHost) CmdArgs.push_back("-g"); for (const auto& II : Inputs) { @@ -498,7 +510,7 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); } else assert(Output.isNothing() && "Invalid output."); - if (mustEmitDebugInfo(Args) == FullDebug) + if (mustEmitDebugInfo(Args) == EmitSameDebugInfoAsHost) CmdArgs.push_back("-g"); if (Args.hasArg(options::OPT_v)) @@ -704,6 +716,21 @@ bool CudaToolChain::supportsDebugInfoOption(const llvm::opt::Arg *A) const { O.matches(options::OPT_gcolumn_info); } +void CudaToolChain::adjustDebugInfoKind( + codegenoptions::DebugInfoKind &DebugInfoKind, const ArgList &Args) const { + switch (mustEmitDebugInfo(Args)) { + case DisableDebugInfo: + DebugInfoKind = codegenoptions::NoDebugInfo; + break; + case DebugDirectivesOnly: + DebugInfoKind = codegenoptions::DebugDirectivesOnly; + break; + case EmitSameDebugInfoAsHost: + // Use same debug info level as the host. + break; + } +} + void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { // Check our CUDA version if we're going to include the CUDA headers. diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h index 01580cb669..1d63ede411 100644 --- a/lib/Driver/ToolChains/Cuda.h +++ b/lib/Driver/ToolChains/Cuda.h @@ -159,6 +159,8 @@ public: bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; + void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, + const llvm::opt::ArgList &Args) const override; bool IsMathErrnoDefault() const override { return false; } void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, diff --git a/test/Driver/cuda-dwarf-2.cu b/test/Driver/cuda-dwarf-2.cu index 7956e6ddbe..bcfb2444bc 100644 --- a/test/Driver/cuda-dwarf-2.cu +++ b/test/Driver/cuda-dwarf-2.cu @@ -1,25 +1,28 @@ // REQUIRES: clang-driver // -// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O0 --no-cuda-noopt-device-debug 2>&1 | \ -// RUN: FileCheck %s -check-prefix NO_DEBUG +// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O1 --no-cuda-noopt-device-debug 2>&1 | \ +// RUN: FileCheck %s -check-prefix DEBUG_DIRECTIVES // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O3 2>&1 | \ -// RUN: FileCheck %s -check-prefix NO_DEBUG +// RUN: FileCheck %s -check-prefix DEBUG_DIRECTIVES // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O3 --no-cuda-noopt-device-debug 2>&1 | \ -// RUN: FileCheck %s -check-prefix NO_DEBUG +// RUN: FileCheck %s -check-prefix DEBUG_DIRECTIVES // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g0 2>&1 | \ // RUN: FileCheck %s -check-prefix NO_DEBUG // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -ggdb0 -O3 --cuda-noopt-device-debug 2>&1 | \ // RUN: FileCheck %s -check-prefix NO_DEBUG -// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -ggdb1 2>&1 | \ -// RUN: FileCheck %s -check-prefix NO_DEBUG -check-prefix LINE_TABLE -// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -gline-tables-only -O2 --cuda-noopt-device-debug 2>&1 | \ -// RUN: FileCheck %s -check-prefix NO_DEBUG -check-prefix LINE_TABLE +// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -gline-directives-only -O2 --cuda-noopt-device-debug 2>&1 | \ +// RUN: FileCheck %s -check-prefix DEBUG_DIRECTIVES // NO_DEBUG-NOT: warning: debug -// LINE_TABLE-NOT: warning: debug +// DEBUG_DIRECTIVES-NOT: warning: debug +// NO_DEBUG: "-fcuda-is-device" +// NO_DEBUG-NOT: "-debug-info-kind= // NO_DEBUG: ptxas // NO_DEBUG-NOT: "-g" -// LINE_TABLE: "-lineinfo" +// DEBUG_DIRECTIVES: "-fcuda-is-device" +// DEBUG_DIRECTIVES-SAME: "-debug-info-kind=line-directives-only" +// DEBUG_DIRECTIVES: ptxas +// DEBUG_DIRECTIVES-SAME: "-lineinfo" // NO_DEBUG: fatbinary // NO_DEBUG-NOT: "-g" @@ -27,6 +30,8 @@ // RUN: FileCheck %s -check-prefix HAS_DEBUG // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O0 --cuda-noopt-device-debug 2>&1 | \ // RUN: FileCheck %s -check-prefix HAS_DEBUG +// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O0 --no-cuda-noopt-device-debug 2>&1 | \ +// RUN: FileCheck %s -check-prefix HAS_DEBUG // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g -O3 --cuda-noopt-device-debug 2>&1 | \ // RUN: FileCheck %s -check-prefix HAS_DEBUG // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -g2 2>&1 | \ @@ -37,9 +42,14 @@ // RUN: FileCheck %s -check-prefix HAS_DEBUG // RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -ggdb3 -O3 --cuda-noopt-device-debug 2>&1 | \ // RUN: FileCheck %s -check-prefix HAS_DEBUG +// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -ggdb1 2>&1 | \ +// RUN: FileCheck %s -check-prefix HAS_DEBUG +// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -gline-tables-only -O2 --cuda-noopt-device-debug 2>&1 | \ +// RUN: FileCheck %s -check-prefix HAS_DEBUG // HAS_DEBUG-NOT: warning: debug // HAS_DEBUG: "-fcuda-is-device" +// HAS_DEBUG-SAME: "-debug-info-kind={{limited|line-tables-only}}" // HAS_DEBUG-SAME: "-dwarf-version=2" // HAS_DEBUG: ptxas // HAS_DEBUG-SAME: "-g" diff --git a/test/Driver/openmp-offload-gpu.c b/test/Driver/openmp-offload-gpu.c index 940828b82b..dfdc79b5f7 100644 --- a/test/Driver/openmp-offload-gpu.c +++ b/test/Driver/openmp-offload-gpu.c @@ -190,29 +190,35 @@ // CHK-BCLIB-WARN: No library 'libomptarget-nvptx-sm_20.bc' found in the default clang lib directory or in LIBRARY_PATH. Expect degraded performance due to no inlining of runtime functions on target devices. /// Check that debug info is emitted in dwarf-2 -// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O0 --no-cuda-noopt-device-debug 2>&1 \ -// RUN: | FileCheck -check-prefix=NO_DEBUG %s +// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O1 --no-cuda-noopt-device-debug 2>&1 \ +// RUN: | FileCheck -check-prefix=DEBUG_DIRECTIVES %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O3 2>&1 \ -// RUN: | FileCheck -check-prefix=NO_DEBUG %s +// RUN: | FileCheck -check-prefix=DEBUG_DIRECTIVES %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O3 --no-cuda-noopt-device-debug 2>&1 \ -// RUN: | FileCheck -check-prefix=NO_DEBUG %s +// RUN: | FileCheck -check-prefix=DEBUG_DIRECTIVES %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g0 2>&1 \ // RUN: | FileCheck -check-prefix=NO_DEBUG %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb0 -O3 --cuda-noopt-device-debug 2>&1 \ // RUN: | FileCheck -check-prefix=NO_DEBUG %s -// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -gline-tables-only 2>&1 \ -// RUN: | FileCheck -check-prefix=NO_DEBUG -check-prefix=LINE_TABLE %s -// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb1 -O2 --cuda-noopt-device-debug 2>&1 \ -// RUN: | FileCheck -check-prefix=NO_DEBUG -check-prefix=LINE_TABLE %s +// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -gline-directives-only 2>&1 \ +// RUN: | FileCheck -check-prefix=DEBUG_DIRECTIVES %s -// LINE_TABLE-NOT: warning: debug +// DEBUG_DIRECTIVES-NOT: warning: debug // NO_DEBUG-NOT: warning: debug +// NO_DEBUG: "-fopenmp-is-device" +// NO_DEBUG-NOT: "-debug-info-kind= // NO_DEBUG: ptxas -// LINE_TABLE: "-lineinfo" +// DEBUG_DIRECTIVES: "-triple" "nvptx64-nvidia-cuda" +// DEBUG_DIRECTIVES-SAME: "-debug-info-kind=line-directives-only" +// DEBUG_DIRECTIVES-SAME: "-fopenmp-is-device" +// DEBUG_DIRECTIVES: ptxas +// DEBUG_DIRECTIVES: "-lineinfo" // NO_DEBUG-NOT: "-g" // NO_DEBUG: nvlink // NO_DEBUG-NOT: "-g" +// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O0 --no-cuda-noopt-device-debug 2>&1 \ +// RUN: | FileCheck -check-prefix=HAS_DEBUG %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g 2>&1 \ // RUN: | FileCheck -check-prefix=HAS_DEBUG %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -g -O0 --cuda-noopt-device-debug 2>&1 \ @@ -227,9 +233,14 @@ // RUN: | FileCheck -check-prefix=HAS_DEBUG %s // RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb3 -O2 --cuda-noopt-device-debug 2>&1 \ // RUN: | FileCheck -check-prefix=HAS_DEBUG %s +// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -gline-tables-only 2>&1 \ +// RUN: | FileCheck -check-prefix=HAS_DEBUG %s +// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb1 -O2 --cuda-noopt-device-debug 2>&1 \ +// RUN: | FileCheck -check-prefix=HAS_DEBUG %s // HAS_DEBUG-NOT: warning: debug // HAS_DEBUG: "-triple" "nvptx64-nvidia-cuda" +// HAS_DEBUG-SAME: "-debug-info-kind={{limited|line-tables-only}}" // HAS_DEBUG-SAME: "-dwarf-version=2" // HAS_DEBUG-SAME: "-fopenmp-is-device" // HAS_DEBUG: ptxas -- 2.40.0