Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "AMDGPUOpenMP.h"
10
#include "AMDGPU.h"
11
#include "CommonArgs.h"
12
#include "ToolChains/ROCm.h"
13
#include "clang/Basic/DiagnosticDriver.h"
14
#include "clang/Driver/Compilation.h"
15
#include "clang/Driver/Driver.h"
16
#include "clang/Driver/DriverDiagnostic.h"
17
#include "clang/Driver/InputInfo.h"
18
#include "clang/Driver/Options.h"
19
#include "clang/Driver/Tool.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/Support/FileSystem.h"
22
#include "llvm/Support/FormatAdapters.h"
23
#include "llvm/Support/FormatVariadic.h"
24
#include "llvm/Support/Path.h"
25
26
using namespace clang::driver;
27
using namespace clang::driver::toolchains;
28
using namespace clang::driver::tools;
29
using namespace clang;
30
using namespace llvm::opt;
31
32
AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
33
                                             const llvm::Triple &Triple,
34
                                             const ToolChain &HostTC,
35
                                             const ArgList &Args)
36
18
    : ROCMToolChain(D, Triple, Args), HostTC(HostTC) {
37
  // Lookup binaries into the driver directory, this is used to
38
  // discover the 'amdgpu-arch' executable.
39
18
  getProgramPaths().push_back(getDriver().Dir);
40
18
}
41
42
void AMDGPUOpenMPToolChain::addClangTargetOptions(
43
    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
44
9
    Action::OffloadKind DeviceOffloadingKind) const {
45
9
  HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
46
47
9
  StringRef GPUArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
48
9
  assert(!GPUArch.empty() && "Must have an explicit GPU arch.");
49
50
9
  assert(DeviceOffloadingKind == Action::OFK_OpenMP &&
51
9
         "Only OpenMP offloading kinds are supported.");
52
53
9
  CC1Args.push_back("-target-cpu");
54
9
  CC1Args.push_back(DriverArgs.MakeArgStringRef(GPUArch));
55
9
  CC1Args.push_back("-fcuda-is-device");
56
57
9
  if (DriverArgs.hasArg(options::OPT_nogpulib))
58
8
    return;
59
60
9
  
for (auto BCFile : getDeviceLibs(DriverArgs))1
{
61
9
    CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
62
9
                                               : 
"-mlink-bitcode-file"0
);
63
9
    CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
64
9
  }
65
66
  // Link the bitcode library late if we're using device LTO.
67
1
  if (getDriver().isUsingLTO(/* IsOffload */ true))
68
0
    return;
69
1
}
70
71
llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
72
    const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
73
15
    Action::OffloadKind DeviceOffloadKind) const {
74
15
  DerivedArgList *DAL =
75
15
      HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
76
15
  if (!DAL)
77
2
    DAL = new DerivedArgList(Args.getBaseArgs());
78
79
15
  const OptTable &Opts = getDriver().getOpts();
80
81
15
  if (DeviceOffloadKind == Action::OFK_OpenMP) {
82
13
    for (Arg *A : Args)
83
111
      if (!llvm::is_contained(*DAL, A))
84
0
        DAL->append(A);
85
86
13
    if (!DAL->hasArg(options::OPT_march_EQ)) {
87
9
      StringRef Arch = BoundArch;
88
9
      if (Arch.empty()) {
89
0
        auto ArchsOrErr = getSystemGPUArchs(Args);
90
0
        if (!ArchsOrErr) {
91
0
          std::string ErrMsg =
92
0
              llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr.takeError()));
93
0
          getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
94
0
              << llvm::Triple::getArchTypeName(getArch()) << ErrMsg << "-march";
95
0
          Arch = CudaArchToString(CudaArch::HIPDefault);
96
0
        } else {
97
0
          Arch = Args.MakeArgString(ArchsOrErr->front());
98
0
        }
99
0
      }
100
9
      DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
101
9
    }
102
103
13
    return DAL;
104
13
  }
105
106
22
  
for (Arg *A : Args)2
{
107
22
    DAL->append(A);
108
22
  }
109
110
2
  if (!BoundArch.empty()) {
111
1
    DAL->eraseArg(options::OPT_march_EQ);
112
1
    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
113
1
                      BoundArch);
114
1
  }
115
116
2
  return DAL;
117
15
}
118
119
void AMDGPUOpenMPToolChain::addClangWarningOptions(
120
9
    ArgStringList &CC1Args) const {
121
9
  HostTC.addClangWarningOptions(CC1Args);
122
9
}
123
124
ToolChain::CXXStdlibType
125
0
AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList &Args) const {
126
0
  return HostTC.GetCXXStdlibType(Args);
127
0
}
128
129
void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
130
17
    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
131
17
  HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
132
17
}
133
134
void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
135
0
                                                ArgStringList &CC1Args) const {
136
0
  HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
137
0
}
138
139
9
SanitizerMask AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
140
  // The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
141
  // allows sanitizer arguments on the command line if they are supported by the
142
  // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
143
  // line arguments for any of these "supported" sanitizers. That means that no
144
  // sanitization of device code is actually supported at this time.
145
  //
146
  // This behavior is necessary because the host and device toolchains
147
  // invocations often share the command line, so the device toolchain must
148
  // tolerate flags meant only for the host toolchain.
149
9
  return HostTC.getSupportedSanitizers();
150
9
}
151
152
VersionTuple
153
AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D,
154
9
                                          const ArgList &Args) const {
155
9
  return HostTC.computeMSVCVersion(D, Args);
156
9
}
157
158
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
159
1
AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const {
160
1
  if (Args.hasArg(options::OPT_nogpulib))
161
0
    return {};
162
163
1
  if (!RocmInstallation->hasDeviceLibrary()) {
164
0
    getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
165
0
    return {};
166
0
  }
167
168
1
  StringRef GpuArch = getProcessorFromTargetID(
169
1
      getTriple(), Args.getLastArgValue(options::OPT_march_EQ));
170
171
1
  SmallVector<BitCodeLibraryInfo, 12> BCLibs;
172
1
  for (auto BCLib : getCommonDeviceLibNames(Args, GpuArch.str(),
173
1
                                            /*IsOpenMP=*/true))
174
9
    BCLibs.emplace_back(BCLib);
175
176
1
  return BCLibs;
177
1
}