Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CommonArgs.cpp - Args handling for multiple toolchains -*- 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 "CommonArgs.h"
10
#include "Arch/AArch64.h"
11
#include "Arch/ARM.h"
12
#include "Arch/M68k.h"
13
#include "Arch/Mips.h"
14
#include "Arch/PPC.h"
15
#include "Arch/SystemZ.h"
16
#include "Arch/VE.h"
17
#include "Arch/X86.h"
18
#include "HIPAMD.h"
19
#include "Hexagon.h"
20
#include "clang/Basic/CharInfo.h"
21
#include "clang/Basic/LangOptions.h"
22
#include "clang/Basic/ObjCRuntime.h"
23
#include "clang/Basic/Version.h"
24
#include "clang/Config/config.h"
25
#include "clang/Driver/Action.h"
26
#include "clang/Driver/Compilation.h"
27
#include "clang/Driver/Driver.h"
28
#include "clang/Driver/DriverDiagnostic.h"
29
#include "clang/Driver/InputInfo.h"
30
#include "clang/Driver/Job.h"
31
#include "clang/Driver/Options.h"
32
#include "clang/Driver/SanitizerArgs.h"
33
#include "clang/Driver/ToolChain.h"
34
#include "clang/Driver/Util.h"
35
#include "clang/Driver/XRayArgs.h"
36
#include "llvm/ADT/STLExtras.h"
37
#include "llvm/ADT/SmallSet.h"
38
#include "llvm/ADT/SmallString.h"
39
#include "llvm/ADT/StringExtras.h"
40
#include "llvm/ADT/StringSwitch.h"
41
#include "llvm/ADT/Twine.h"
42
#include "llvm/Config/llvm-config.h"
43
#include "llvm/Option/Arg.h"
44
#include "llvm/Option/ArgList.h"
45
#include "llvm/Option/Option.h"
46
#include "llvm/Support/CodeGen.h"
47
#include "llvm/Support/Compression.h"
48
#include "llvm/Support/Debug.h"
49
#include "llvm/Support/ErrorHandling.h"
50
#include "llvm/Support/FileSystem.h"
51
#include "llvm/Support/Host.h"
52
#include "llvm/Support/Path.h"
53
#include "llvm/Support/Process.h"
54
#include "llvm/Support/Program.h"
55
#include "llvm/Support/ScopedPrinter.h"
56
#include "llvm/Support/TargetParser.h"
57
#include "llvm/Support/Threading.h"
58
#include "llvm/Support/VirtualFileSystem.h"
59
#include "llvm/Support/YAMLParser.h"
60
61
using namespace clang::driver;
62
using namespace clang::driver::tools;
63
using namespace clang;
64
using namespace llvm::opt;
65
66
84
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs) {
67
84
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
68
2
    CmdArgs.push_back(Args.MakeArgString(Twine("--plugin-opt=-pass-remarks=") +
69
2
                                         A->getValue()));
70
71
84
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
72
2
    CmdArgs.push_back(Args.MakeArgString(
73
2
        Twine("--plugin-opt=-pass-remarks-missed=") + A->getValue()));
74
75
84
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
76
2
    CmdArgs.push_back(Args.MakeArgString(
77
2
        Twine("--plugin-opt=-pass-remarks-analysis=") + A->getValue()));
78
84
}
79
80
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
81
                                 const llvm::Triple &Triple,
82
                                 const InputInfo &Input,
83
3
                                 const InputInfo &Output) {
84
3
  StringRef Format = "yaml";
85
3
  if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
86
1
    Format = A->getValue();
87
88
3
  SmallString<128> F;
89
3
  const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
90
3
  if (A)
91
1
    F = A->getValue();
92
2
  else if (Output.isFilename())
93
2
    F = Output.getFilename();
94
95
3
  assert(!F.empty() && "Cannot determine remarks output name.");
96
  // Append "opt.ld.<format>" to the end of the file name.
97
0
  CmdArgs.push_back(
98
3
      Args.MakeArgString(Twine("--plugin-opt=opt-remarks-filename=") + F +
99
3
                         Twine(".opt.ld.") + Format));
100
101
3
  if (const Arg *A =
102
3
          Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
103
2
    CmdArgs.push_back(Args.MakeArgString(
104
2
        Twine("--plugin-opt=opt-remarks-passes=") + A->getValue()));
105
106
3
  CmdArgs.push_back(Args.MakeArgString(
107
3
      Twine("--plugin-opt=opt-remarks-format=") + Format.data()));
108
3
}
109
110
static void renderRemarksHotnessOptions(const ArgList &Args,
111
84
                                        ArgStringList &CmdArgs) {
112
84
  if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
113
84
                   options::OPT_fno_diagnostics_show_hotness, false))
114
0
    CmdArgs.push_back("--plugin-opt=opt-remarks-with-hotness");
115
116
84
  if (const Arg *A =
117
84
          Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
118
5
    CmdArgs.push_back(Args.MakeArgString(
119
5
        Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue()));
120
84
}
121
122
void tools::addPathIfExists(const Driver &D, const Twine &Path,
123
35.6k
                            ToolChain::path_list &Paths) {
124
35.6k
  if (D.getVFS().exists(Path))
125
8.44k
    Paths.push_back(Path.str());
126
35.6k
}
127
128
void tools::handleTargetFeaturesGroup(const ArgList &Args,
129
                                      std::vector<StringRef> &Features,
130
1.22k
                                      OptSpecifier Group) {
131
1.22k
  for (const Arg *A : Args.filtered(Group)) {
132
171
    StringRef Name = A->getOption().getName();
133
171
    A->claim();
134
135
    // Skip over "-m".
136
171
    assert(Name.startswith("m") && "Invalid feature name.");
137
0
    Name = Name.substr(1);
138
139
171
    bool IsNegative = Name.startswith("no-");
140
171
    if (IsNegative)
141
54
      Name = Name.substr(3);
142
171
    Features.push_back(Args.MakeArgString((IsNegative ? 
"-"54
:
"+"117
) + Name));
143
171
  }
144
1.22k
}
145
146
std::vector<StringRef>
147
43.6k
tools::unifyTargetFeatures(const std::vector<StringRef> &Features) {
148
43.6k
  std::vector<StringRef> UnifiedFeatures;
149
  // Find the last of each feature.
150
43.6k
  llvm::StringMap<unsigned> LastOpt;
151
140k
  for (unsigned I = 0, N = Features.size(); I < N; 
++I97.1k
) {
152
97.1k
    StringRef Name = Features[I];
153
97.1k
    assert(Name[0] == '-' || Name[0] == '+');
154
0
    LastOpt[Name.drop_front(1)] = I;
155
97.1k
  }
156
157
140k
  for (unsigned I = 0, N = Features.size(); I < N; 
++I97.1k
) {
158
    // If this feature was overridden, ignore it.
159
97.1k
    StringRef Name = Features[I];
160
97.1k
    llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1));
161
97.1k
    assert(LastI != LastOpt.end());
162
0
    unsigned Last = LastI->second;
163
97.1k
    if (Last != I)
164
23.8k
      continue;
165
166
73.2k
    UnifiedFeatures.push_back(Name);
167
73.2k
  }
168
43.6k
  return UnifiedFeatures;
169
43.6k
}
170
171
void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
172
219k
                             const char *ArgName, const char *EnvVar) {
173
219k
  const char *DirList = ::getenv(EnvVar);
174
219k
  bool CombinedArg = false;
175
176
219k
  if (!DirList)
177
219k
    return; // Nothing to do.
178
179
61
  StringRef Name(ArgName);
180
61
  if (Name.equals("-I") || 
Name.equals("-L")38
||
Name.empty()9
)
181
57
    CombinedArg = true;
182
183
61
  StringRef Dirs(DirList);
184
61
  if (Dirs.empty()) // Empty string should not add '.'.
185
0
    return;
186
187
61
  StringRef::size_type Delim;
188
64
  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
189
3
    if (Delim == 0) { // Leading colon.
190
0
      if (CombinedArg) {
191
0
        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
192
0
      } else {
193
0
        CmdArgs.push_back(ArgName);
194
0
        CmdArgs.push_back(".");
195
0
      }
196
3
    } else {
197
3
      if (CombinedArg) {
198
1
        CmdArgs.push_back(
199
1
            Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
200
2
      } else {
201
2
        CmdArgs.push_back(ArgName);
202
2
        CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
203
2
      }
204
3
    }
205
3
    Dirs = Dirs.substr(Delim + 1);
206
3
  }
207
208
61
  if (Dirs.empty()) { // Trailing colon.
209
0
    if (CombinedArg) {
210
0
      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
211
0
    } else {
212
0
      CmdArgs.push_back(ArgName);
213
0
      CmdArgs.push_back(".");
214
0
    }
215
61
  } else { // Add the last path.
216
61
    if (CombinedArg) {
217
57
      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
218
57
    } else {
219
4
      CmdArgs.push_back(ArgName);
220
4
      CmdArgs.push_back(Args.MakeArgString(Dirs));
221
4
    }
222
61
  }
223
61
}
224
225
void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
226
                            const ArgList &Args, ArgStringList &CmdArgs,
227
5.97k
                            const JobAction &JA) {
228
5.97k
  const Driver &D = TC.getDriver();
229
230
  // Add extra linker input arguments which are not treated as inputs
231
  // (constructed via -Xarch_).
232
5.97k
  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
233
234
  // LIBRARY_PATH are included before user inputs and only supported on native
235
  // toolchains.
236
5.97k
  if (!TC.isCrossCompiling())
237
4.37k
    addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
238
239
7.51k
  for (const auto &II : Inputs) {
240
    // If the current tool chain refers to an OpenMP offloading host, we
241
    // should ignore inputs that refer to OpenMP offloading devices -
242
    // they will be embedded according to a proper linker script.
243
7.51k
    if (auto *IA = II.getAction())
244
7.51k
      if ((JA.isHostOffloading(Action::OFK_OpenMP) &&
245
7.51k
           
IA->isDeviceOffloading(Action::OFK_OpenMP)0
))
246
0
        continue;
247
248
7.51k
    if (!TC.HasNativeLLVMSupport() && 
types::isLLVMIR(II.getType())687
)
249
      // Don't try to pass LLVM inputs unless we have native support.
250
4
      D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
251
252
    // Add filenames immediately.
253
7.51k
    if (II.isFilename()) {
254
6.37k
      CmdArgs.push_back(II.getFilename());
255
6.37k
      continue;
256
6.37k
    }
257
258
    // Otherwise, this is a linker input argument.
259
1.13k
    const Arg &A = II.getInputArg();
260
261
    // Handle reserved library options.
262
1.13k
    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
263
3
      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
264
1.13k
    else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
265
2
      TC.AddCCKextLibArgs(Args, CmdArgs);
266
1.12k
    else if (A.getOption().matches(options::OPT_z)) {
267
      // Pass -z prefix for gcc linker compatibility.
268
3
      A.claim();
269
3
      A.render(Args, CmdArgs);
270
1.12k
    } else if (A.getOption().matches(options::OPT_b)) {
271
3
      const llvm::Triple &T = TC.getTriple();
272
3
      if (!T.isOSAIX()) {
273
1
        TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
274
1
            << A.getSpelling() << T.str();
275
1
      }
276
      // Pass -b prefix for AIX linker.
277
3
      A.claim();
278
3
      A.render(Args, CmdArgs);
279
1.12k
    } else {
280
1.12k
      A.renderAsInput(Args, CmdArgs);
281
1.12k
    }
282
1.13k
  }
283
5.97k
}
284
285
void tools::addLinkerCompressDebugSectionsOption(
286
    const ToolChain &TC, const llvm::opt::ArgList &Args,
287
1.47k
    llvm::opt::ArgStringList &CmdArgs) {
288
  // GNU ld supports --compress-debug-sections=none|zlib|zlib-gnu|zlib-gabi
289
  // whereas zlib is an alias to zlib-gabi. Therefore -gz=none|zlib|zlib-gnu
290
  // are translated to --compress-debug-sections=none|zlib|zlib-gnu.
291
  // -gz is not translated since ld --compress-debug-sections option requires an
292
  // argument.
293
1.47k
  if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) {
294
7
    StringRef V = A->getValue();
295
7
    if (V == "none" || 
V == "zlib"5
||
V == "zlib-gnu"2
)
296
7
      CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V));
297
0
    else
298
0
      TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
299
0
          << A->getOption().getName() << V;
300
7
  }
301
1.47k
}
302
303
void tools::AddTargetFeature(const ArgList &Args,
304
                             std::vector<StringRef> &Features,
305
                             OptSpecifier OnOpt, OptSpecifier OffOpt,
306
5.46k
                             StringRef FeatureName) {
307
5.46k
  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
308
78
    if (A->getOption().matches(OnOpt))
309
51
      Features.push_back(Args.MakeArgString("+" + FeatureName));
310
27
    else
311
27
      Features.push_back(Args.MakeArgString("-" + FeatureName));
312
78
  }
313
5.46k
}
314
315
/// Get the (LLVM) name of the AMDGPU gpu we are targeting.
316
static std::string getAMDGPUTargetGPU(const llvm::Triple &T,
317
184
                                      const ArgList &Args) {
318
184
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
319
163
    auto GPUName = getProcessorFromTargetID(T, A->getValue());
320
163
    return llvm::StringSwitch<std::string>(GPUName)
321
163
        .Cases("rv630", "rv635", "r600")
322
163
        .Cases("rv610", "rv620", "rs780", "rs880")
323
163
        .Case("rv740", "rv770")
324
163
        .Case("palm", "cedar")
325
163
        .Cases("sumo", "sumo2", "sumo")
326
163
        .Case("hemlock", "cypress")
327
163
        .Case("aruba", "cayman")
328
163
        .Default(GPUName.str());
329
163
  }
330
21
  return "";
331
184
}
332
333
3
static std::string getLanaiTargetCPU(const ArgList &Args) {
334
3
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
335
0
    return A->getValue();
336
0
  }
337
3
  return "";
338
3
}
339
340
/// Get the (LLVM) name of the WebAssembly cpu we are targeting.
341
99
static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
342
  // If we have -mcpu=, use that.
343
99
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
344
6
    StringRef CPU = A->getValue();
345
346
#ifdef __wasm__
347
    // Handle "native" by examining the host. "native" isn't meaningful when
348
    // cross compiling, so only support this when the host is also WebAssembly.
349
    if (CPU == "native")
350
      return llvm::sys::getHostCPUName();
351
#endif
352
353
6
    return CPU;
354
6
  }
355
356
93
  return "generic";
357
99
}
358
359
std::string tools::getCPUName(const Driver &D, const ArgList &Args,
360
46.0k
                              const llvm::Triple &T, bool FromAs) {
361
46.0k
  Arg *A;
362
363
46.0k
  switch (T.getArch()) {
364
128
  default:
365
128
    return "";
366
367
1.26k
  case llvm::Triple::aarch64:
368
1.26k
  case llvm::Triple::aarch64_32:
369
1.47k
  case llvm::Triple::aarch64_be:
370
1.47k
    return aarch64::getAArch64TargetCPU(Args, T, A);
371
372
2.17k
  case llvm::Triple::arm:
373
2.54k
  case llvm::Triple::armeb:
374
3.77k
  case llvm::Triple::thumb:
375
3.98k
  case llvm::Triple::thumbeb: {
376
3.98k
    StringRef MArch, MCPU;
377
3.98k
    arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
378
3.98k
    return arm::getARMTargetCPU(MCPU, MArch, T);
379
3.77k
  }
380
381
216
  case llvm::Triple::avr:
382
216
    if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ))
383
193
      return A->getValue();
384
23
    return "";
385
386
30
  case llvm::Triple::m68k:
387
30
    return m68k::getM68kTargetCPU(Args);
388
389
274
  case llvm::Triple::mips:
390
358
  case llvm::Triple::mipsel:
391
446
  case llvm::Triple::mips64:
392
525
  case llvm::Triple::mips64el: {
393
525
    StringRef CPUName;
394
525
    StringRef ABIName;
395
525
    mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
396
525
    return std::string(CPUName);
397
446
  }
398
399
5
  case llvm::Triple::nvptx:
400
52
  case llvm::Triple::nvptx64:
401
52
    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
402
52
      return A->getValue();
403
0
    return "";
404
405
157
  case llvm::Triple::ppc:
406
165
  case llvm::Triple::ppcle:
407
354
  case llvm::Triple::ppc64:
408
446
  case llvm::Triple::ppc64le: {
409
446
    std::string TargetCPUName = ppc::getPPCTargetCPU(Args);
410
    // LLVM may default to generating code for the native CPU,
411
    // but, like gcc, we default to a more generic option for
412
    // each architecture. (except on AIX)
413
446
    if (!TargetCPUName.empty())
414
115
      return TargetCPUName;
415
416
331
    if (T.isOSAIX())
417
126
      TargetCPUName = "pwr7";
418
205
    else if (T.getArch() == llvm::Triple::ppc64le)
419
57
      TargetCPUName = "ppc64le";
420
148
    else if (T.getArch() == llvm::Triple::ppc64)
421
88
      TargetCPUName = "ppc64";
422
60
    else
423
60
      TargetCPUName = "ppc";
424
425
331
    return TargetCPUName;
426
446
  }
427
228
  case llvm::Triple::riscv32:
428
442
  case llvm::Triple::riscv64:
429
442
    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
430
21
      return A->getValue();
431
421
    return "";
432
433
3
  case llvm::Triple::bpfel:
434
6
  case llvm::Triple::bpfeb:
435
171
  case llvm::Triple::sparc:
436
180
  case llvm::Triple::sparcel:
437
278
  case llvm::Triple::sparcv9:
438
278
    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
439
116
      return A->getValue();
440
162
    if (T.getArch() == llvm::Triple::sparc && 
T.isOSSolaris()87
)
441
18
      return "v9";
442
144
    return "";
443
444
10.7k
  case llvm::Triple::x86:
445
37.9k
  case llvm::Triple::x86_64:
446
37.9k
    return x86::getX86TargetCPU(D, Args, T);
447
448
120
  case llvm::Triple::hexagon:
449
120
    return "hexagon" +
450
120
           toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
451
452
3
  case llvm::Triple::lanai:
453
3
    return getLanaiTargetCPU(Args);
454
455
56
  case llvm::Triple::systemz:
456
56
    return systemz::getSystemZTargetCPU(Args);
457
458
26
  case llvm::Triple::r600:
459
184
  case llvm::Triple::amdgcn:
460
184
    return getAMDGPUTargetGPU(T, Args);
461
462
70
  case llvm::Triple::wasm32:
463
99
  case llvm::Triple::wasm64:
464
99
    return std::string(getWebAssemblyTargetCPU(Args));
465
46.0k
  }
466
46.0k
}
467
468
3.69k
llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
469
3.69k
  Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
470
3.69k
  if (!LtoJobsArg)
471
3.69k
    return {};
472
3
  if (!llvm::get_threadpool_strategy(LtoJobsArg->getValue()))
473
0
    D.Diag(diag::err_drv_invalid_int_value)
474
0
        << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue();
475
3
  return LtoJobsArg->getValue();
476
3.69k
}
477
478
// CloudABI uses -ffunction-sections and -fdata-sections by default.
479
43.2k
bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
480
43.2k
  return Triple.getOS() == llvm::Triple::CloudABI;
481
43.2k
}
482
483
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
484
                          ArgStringList &CmdArgs, const InputInfo &Output,
485
84
                          const InputInfo &Input, bool IsThinLTO) {
486
84
  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
487
84
  const Driver &D = ToolChain.getDriver();
488
84
  if (llvm::sys::path::filename(Linker) != "ld.lld" &&
489
84
      
llvm::sys::path::stem(Linker) != "ld.lld"55
) {
490
    // Tell the linker to load the plugin. This has to come before
491
    // AddLinkerInputs as gold requires -plugin to come before any -plugin-opt
492
    // that -Wl might forward.
493
55
    CmdArgs.push_back("-plugin");
494
495
#if defined(_WIN32)
496
    const char *Suffix = ".dll";
497
#elif defined(__APPLE__)
498
55
    const char *Suffix = ".dylib";
499
#else
500
    const char *Suffix = ".so";
501
#endif
502
503
55
    SmallString<1024> Plugin;
504
55
    llvm::sys::path::native(
505
55
        Twine(D.Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix,
506
55
        Plugin);
507
55
    CmdArgs.push_back(Args.MakeArgString(Plugin));
508
55
  }
509
510
  // Try to pass driver level flags relevant to LTO code generation down to
511
  // the plugin.
512
513
  // Handle flags for selecting CPU variants.
514
84
  std::string CPU = getCPUName(D, Args, ToolChain.getTriple());
515
84
  if (!CPU.empty())
516
84
    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
517
518
84
  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
519
    // The optimization level matches
520
    // CompilerInvocation.cpp:getOptimizationLevel().
521
11
    StringRef OOpt;
522
11
    if (A->getOption().matches(options::OPT_O4) ||
523
11
        A->getOption().matches(options::OPT_Ofast))
524
1
      OOpt = "3";
525
10
    else if (A->getOption().matches(options::OPT_O)) {
526
10
      OOpt = A->getValue();
527
10
      if (OOpt == "g")
528
1
        OOpt = "1";
529
9
      else if (OOpt == "s" || 
OOpt == "z"8
)
530
2
        OOpt = "2";
531
10
    } else 
if (0
A->getOption().matches(options::OPT_O0)0
)
532
0
      OOpt = "0";
533
11
    if (!OOpt.empty())
534
11
      CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
535
11
  }
536
537
84
  if (Args.hasArg(options::OPT_gsplit_dwarf)) {
538
1
    CmdArgs.push_back(
539
1
        Args.MakeArgString(Twine("-plugin-opt=dwo_dir=") +
540
1
            Output.getFilename() + "_dwo"));
541
1
  }
542
543
84
  if (IsThinLTO)
544
20
    CmdArgs.push_back("-plugin-opt=thinlto");
545
546
84
  StringRef Parallelism = getLTOParallelism(Args, D);
547
84
  if (!Parallelism.empty())
548
2
    CmdArgs.push_back(
549
2
        Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism)));
550
551
  // If an explicit debugger tuning argument appeared, pass it along.
552
84
  if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
553
84
                               options::OPT_ggdbN_Group)) {
554
1
    if (A->getOption().matches(options::OPT_glldb))
555
1
      CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
556
0
    else if (A->getOption().matches(options::OPT_gsce))
557
0
      CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
558
0
    else if (A->getOption().matches(options::OPT_gdbx))
559
0
      CmdArgs.push_back("-plugin-opt=-debugger-tune=dbx");
560
0
    else
561
0
      CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
562
1
  }
563
564
84
  bool UseSeparateSections =
565
84
      isUseSeparateSections(ToolChain.getEffectiveTriple());
566
567
84
  if (Args.hasFlag(options::OPT_ffunction_sections,
568
84
                   options::OPT_fno_function_sections, UseSeparateSections)) {
569
1
    CmdArgs.push_back("-plugin-opt=-function-sections");
570
1
  }
571
572
84
  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
573
84
                   UseSeparateSections)) {
574
1
    CmdArgs.push_back("-plugin-opt=-data-sections");
575
1
  }
576
577
84
  if (Arg *A = getLastProfileSampleUseArg(Args)) {
578
1
    StringRef FName = A->getValue();
579
1
    if (!llvm::sys::fs::exists(FName))
580
0
      D.Diag(diag::err_drv_no_such_file) << FName;
581
1
    else
582
1
      CmdArgs.push_back(
583
1
          Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName));
584
1
  }
585
586
84
  auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
587
84
                                           options::OPT_fcs_profile_generate_EQ,
588
84
                                           options::OPT_fno_profile_generate);
589
84
  if (CSPGOGenerateArg &&
590
84
      
CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)0
)
591
0
    CSPGOGenerateArg = nullptr;
592
593
84
  auto *ProfileUseArg = getLastProfileUseArg(Args);
594
595
84
  if (CSPGOGenerateArg) {
596
0
    CmdArgs.push_back(Args.MakeArgString("-plugin-opt=cs-profile-generate"));
597
0
    if (CSPGOGenerateArg->getOption().matches(
598
0
            options::OPT_fcs_profile_generate_EQ)) {
599
0
      SmallString<128> Path(CSPGOGenerateArg->getValue());
600
0
      llvm::sys::path::append(Path, "default_%m.profraw");
601
0
      CmdArgs.push_back(
602
0
          Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + Path));
603
0
    } else
604
0
      CmdArgs.push_back(
605
0
          Args.MakeArgString("-plugin-opt=cs-profile-path=default_%m.profraw"));
606
84
  } else if (ProfileUseArg) {
607
1
    SmallString<128> Path(
608
1
        ProfileUseArg->getNumValues() == 0 ? "" : 
ProfileUseArg->getValue()0
);
609
1
    if (Path.empty() || 
llvm::sys::fs::is_directory(Path)0
)
610
1
      llvm::sys::path::append(Path, "default.profdata");
611
1
    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") +
612
1
                                         Path));
613
1
  }
614
615
  // Pass an option to enable/disable the new pass manager.
616
84
  if (auto *A = Args.getLastArg(options::OPT_flegacy_pass_manager,
617
84
                                options::OPT_fno_legacy_pass_manager)) {
618
4
    if (A->getOption().matches(options::OPT_flegacy_pass_manager))
619
2
      CmdArgs.push_back("-plugin-opt=legacy-pass-manager");
620
2
    else
621
2
      CmdArgs.push_back("-plugin-opt=new-pass-manager");
622
4
  }
623
624
  // Setup statistics file output.
625
84
  SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
626
84
  if (!StatsFile.empty())
627
2
    CmdArgs.push_back(
628
2
        Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
629
630
84
  addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true);
631
632
  // Handle remark diagnostics on screen options: '-Rpass-*'.
633
84
  renderRpassOptions(Args, CmdArgs);
634
635
  // Handle serialized remarks options: '-fsave-optimization-record'
636
  // and '-foptimization-record-*'.
637
84
  if (willEmitRemarks(Args))
638
3
    renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
639
3
                         Output);
640
641
  // Handle remarks hotness/threshold related options.
642
84
  renderRemarksHotnessOptions(Args, CmdArgs);
643
644
84
  addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(),
645
84
                         /*IsLTO=*/true);
646
84
}
647
648
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
649
98
                                 ArgStringList &CmdArgs) {
650
  // Enable -frtlib-add-rpath by default for the case of VE.
651
98
  const bool IsVE = TC.getTriple().isVE();
652
98
  bool DefaultValue = IsVE;
653
98
  if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
654
98
                    options::OPT_fno_rtlib_add_rpath, DefaultValue))
655
94
    return;
656
657
4
  std::string CandidateRPath = TC.getArchSpecificLibPath();
658
4
  if (TC.getVFS().exists(CandidateRPath)) {
659
4
    CmdArgs.push_back("-rpath");
660
4
    CmdArgs.push_back(Args.MakeArgString(CandidateRPath));
661
4
  }
662
4
}
663
664
bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
665
                             const ArgList &Args, bool ForceStaticHostRuntime,
666
5.21k
                             bool IsOffloadingHost, bool GompNeedsRT) {
667
5.21k
  if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
668
5.21k
                    options::OPT_fno_openmp, false))
669
5.16k
    return false;
670
671
53
  Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args);
672
673
53
  if (RTKind == Driver::OMPRT_Unknown)
674
    // Already diagnosed.
675
2
    return false;
676
677
51
  if (ForceStaticHostRuntime)
678
12
    CmdArgs.push_back("-Bstatic");
679
680
51
  switch (RTKind) {
681
25
  case Driver::OMPRT_OMP:
682
25
    CmdArgs.push_back("-lomp");
683
25
    break;
684
13
  case Driver::OMPRT_GOMP:
685
13
    CmdArgs.push_back("-lgomp");
686
13
    break;
687
13
  case Driver::OMPRT_IOMP5:
688
13
    CmdArgs.push_back("-liomp5");
689
13
    break;
690
0
  case Driver::OMPRT_Unknown:
691
0
    break;
692
51
  }
693
694
51
  if (ForceStaticHostRuntime)
695
12
    CmdArgs.push_back("-Bdynamic");
696
697
51
  if (RTKind == Driver::OMPRT_GOMP && 
GompNeedsRT13
)
698
6
      CmdArgs.push_back("-lrt");
699
700
51
  if (IsOffloadingHost)
701
0
    CmdArgs.push_back("-lomptarget");
702
703
51
  addArchSpecificRPath(TC, Args, CmdArgs);
704
705
51
  return true;
706
51
}
707
708
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
709
                                ArgStringList &CmdArgs, StringRef Sanitizer,
710
500
                                bool IsShared, bool IsWhole) {
711
  // Wrap any static runtimes that must be forced into executable in
712
  // whole-archive.
713
500
  if (IsWhole) 
CmdArgs.push_back("--whole-archive")441
;
714
500
  CmdArgs.push_back(TC.getCompilerRTArgString(
715
500
      Args, Sanitizer, IsShared ? 
ToolChain::FT_Shared47
:
ToolChain::FT_Static453
));
716
500
  if (IsWhole) 
CmdArgs.push_back("--no-whole-archive")441
;
717
718
500
  if (IsShared) {
719
47
    addArchSpecificRPath(TC, Args, CmdArgs);
720
47
  }
721
500
}
722
723
// Tries to use a file with the list of dynamic symbols that need to be exported
724
// from the runtime library. Returns true if the file was found.
725
static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
726
                                    ArgStringList &CmdArgs,
727
322
                                    StringRef Sanitizer) {
728
  // Solaris ld defaults to --export-dynamic behaviour but doesn't support
729
  // the option, so don't try to pass it.
730
322
  if (TC.getTriple().getOS() == llvm::Triple::Solaris)
731
2
    return true;
732
320
  SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
733
320
  if (llvm::sys::fs::exists(SanRT + ".syms")) {
734
20
    CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
735
20
    return true;
736
20
  }
737
300
  return false;
738
320
}
739
740
4.80k
static const char *getAsNeededOption(const ToolChain &TC, bool as_needed) {
741
4.80k
  assert(!TC.getTriple().isOSAIX() &&
742
4.80k
         "AIX linker does not support any form of --as-needed option yet.");
743
744
  // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases
745
  // for the native forms -z ignore/-z record, they are missing in Illumos,
746
  // so always use the native form.
747
4.80k
  if (TC.getTriple().isOSSolaris())
748
2
    return as_needed ? 
"-zignore"0
: "-zrecord";
749
4.80k
  else
750
4.80k
    return as_needed ? 
"--as-needed"2.24k
:
"--no-as-needed"2.55k
;
751
4.80k
}
752
753
void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
754
308
                                     ArgStringList &CmdArgs) {
755
  // Fuchsia never needs these.  Any sanitizer runtimes with system
756
  // dependencies use the `.deplibs` feature instead.
757
308
  if (TC.getTriple().isOSFuchsia())
758
2
    return;
759
760
  // Force linking against the system libraries sanitizers depends on
761
  // (see PR15823 why this is necessary).
762
306
  CmdArgs.push_back(getAsNeededOption(TC, false));
763
  // There's no libpthread or librt on RTEMS & Android.
764
306
  if (TC.getTriple().getOS() != llvm::Triple::RTEMS &&
765
306
      
!TC.getTriple().isAndroid()305
) {
766
302
    CmdArgs.push_back("-lpthread");
767
302
    if (!TC.getTriple().isOSOpenBSD())
768
302
      CmdArgs.push_back("-lrt");
769
302
  }
770
306
  CmdArgs.push_back("-lm");
771
  // There's no libdl on all OSes.
772
306
  if (!TC.getTriple().isOSFreeBSD() && 
!TC.getTriple().isOSNetBSD()302
&&
773
306
      
!TC.getTriple().isOSOpenBSD()284
&&
774
306
      
TC.getTriple().getOS() != llvm::Triple::RTEMS284
)
775
283
    CmdArgs.push_back("-ldl");
776
  // Required for backtrace on some OSes
777
306
  if (TC.getTriple().isOSFreeBSD() ||
778
306
      
TC.getTriple().isOSNetBSD()302
||
779
306
      
TC.getTriple().isOSOpenBSD()284
)
780
22
    CmdArgs.push_back("-lexecinfo");
781
306
}
782
783
static void
784
collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
785
                         SmallVectorImpl<StringRef> &SharedRuntimes,
786
                         SmallVectorImpl<StringRef> &StaticRuntimes,
787
                         SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
788
                         SmallVectorImpl<StringRef> &HelperStaticRuntimes,
789
1.75k
                         SmallVectorImpl<StringRef> &RequiredSymbols) {
790
1.75k
  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
791
  // Collect shared runtimes.
792
1.75k
  if (SanArgs.needsSharedRt()) {
793
227
    if (SanArgs.needsAsanRt() && 
SanArgs.linkRuntimes()24
) {
794
24
      SharedRuntimes.push_back("asan");
795
24
      if (!Args.hasArg(options::OPT_shared) && 
!TC.getTriple().isAndroid()21
)
796
13
        HelperStaticRuntimes.push_back("asan-preinit");
797
24
    }
798
227
    if (SanArgs.needsMemProfRt() && 
SanArgs.linkRuntimes()0
) {
799
0
      SharedRuntimes.push_back("memprof");
800
0
      if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
801
0
        HelperStaticRuntimes.push_back("memprof-preinit");
802
0
    }
803
227
    if (SanArgs.needsUbsanRt() && 
SanArgs.linkRuntimes()7
) {
804
7
      if (SanArgs.requiresMinimalRuntime())
805
0
        SharedRuntimes.push_back("ubsan_minimal");
806
7
      else
807
7
        SharedRuntimes.push_back("ubsan_standalone");
808
7
    }
809
227
    if (SanArgs.needsScudoRt() && 
SanArgs.linkRuntimes()7
) {
810
7
      if (SanArgs.requiresMinimalRuntime())
811
0
        SharedRuntimes.push_back("scudo_minimal");
812
7
      else
813
7
        SharedRuntimes.push_back("scudo");
814
7
    }
815
227
    if (SanArgs.needsTsanRt() && 
SanArgs.linkRuntimes()0
)
816
0
      SharedRuntimes.push_back("tsan");
817
227
    if (SanArgs.needsHwasanRt() && 
SanArgs.linkRuntimes()9
) {
818
9
      if (SanArgs.needsHwasanAliasesRt())
819
0
        SharedRuntimes.push_back("hwasan_aliases");
820
9
      else
821
9
        SharedRuntimes.push_back("hwasan");
822
9
    }
823
227
  }
824
825
  // The stats_client library is also statically linked into DSOs.
826
1.75k
  if (SanArgs.needsStatsRt() && 
SanArgs.linkRuntimes()1
)
827
1
    StaticRuntimes.push_back("stats_client");
828
829
  // Always link the static runtime regardless of DSO or executable.
830
1.75k
  if (SanArgs.needsAsanRt())
831
104
    HelperStaticRuntimes.push_back("asan_static");
832
833
  // Collect static runtimes.
834
1.75k
  if (Args.hasArg(options::OPT_shared)) {
835
    // Don't link static runtimes into DSOs.
836
50
    return;
837
50
  }
838
839
  // Each static runtime that has a DSO counterpart above is excluded below,
840
  // but runtimes that exist only as static are not affected by needsSharedRt.
841
842
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsAsanRt()1.50k
&&
SanArgs.linkRuntimes()80
) {
843
79
    StaticRuntimes.push_back("asan");
844
79
    if (SanArgs.linkCXXRuntimes())
845
2
      StaticRuntimes.push_back("asan_cxx");
846
79
  }
847
848
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsMemProfRt()1.50k
&&
849
1.70k
      
SanArgs.linkRuntimes()2
) {
850
2
    StaticRuntimes.push_back("memprof");
851
2
    if (SanArgs.linkCXXRuntimes())
852
2
      StaticRuntimes.push_back("memprof_cxx");
853
2
  }
854
855
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsHwasanRt()1.50k
&&
SanArgs.linkRuntimes()16
) {
856
16
    if (SanArgs.needsHwasanAliasesRt()) {
857
1
      StaticRuntimes.push_back("hwasan_aliases");
858
1
      if (SanArgs.linkCXXRuntimes())
859
0
        StaticRuntimes.push_back("hwasan_aliases_cxx");
860
15
    } else {
861
15
      StaticRuntimes.push_back("hwasan");
862
15
      if (SanArgs.linkCXXRuntimes())
863
0
        StaticRuntimes.push_back("hwasan_cxx");
864
15
    }
865
16
  }
866
1.70k
  if (SanArgs.needsDfsanRt() && 
SanArgs.linkRuntimes()4
)
867
4
    StaticRuntimes.push_back("dfsan");
868
1.70k
  if (SanArgs.needsLsanRt() && 
SanArgs.linkRuntimes()27
)
869
26
    StaticRuntimes.push_back("lsan");
870
1.70k
  if (SanArgs.needsMsanRt() && 
SanArgs.linkRuntimes()34
) {
871
33
    StaticRuntimes.push_back("msan");
872
33
    if (SanArgs.linkCXXRuntimes())
873
2
      StaticRuntimes.push_back("msan_cxx");
874
33
  }
875
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsTsanRt()1.50k
&&
876
1.70k
      
SanArgs.linkRuntimes()23
) {
877
22
    StaticRuntimes.push_back("tsan");
878
22
    if (SanArgs.linkCXXRuntimes())
879
2
      StaticRuntimes.push_back("tsan_cxx");
880
22
  }
881
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsUbsanRt()1.50k
&&
SanArgs.linkRuntimes()93
) {
882
92
    if (SanArgs.requiresMinimalRuntime()) {
883
7
      StaticRuntimes.push_back("ubsan_minimal");
884
85
    } else {
885
85
      StaticRuntimes.push_back("ubsan_standalone");
886
85
      if (SanArgs.linkCXXRuntimes())
887
2
        StaticRuntimes.push_back("ubsan_standalone_cxx");
888
85
    }
889
92
  }
890
1.70k
  if (SanArgs.needsSafeStackRt() && 
SanArgs.linkRuntimes()11
) {
891
11
    NonWholeStaticRuntimes.push_back("safestack");
892
11
    RequiredSymbols.push_back("__safestack_init");
893
11
  }
894
1.70k
  if (!(SanArgs.needsSharedRt() && 
SanArgs.needsUbsanRt()198
&&
SanArgs.linkRuntimes()6
)) {
895
1.69k
    if (SanArgs.needsCfiRt() && 
SanArgs.linkRuntimes()1
)
896
1
      StaticRuntimes.push_back("cfi");
897
1.69k
    if (SanArgs.needsCfiDiagRt() && 
SanArgs.linkRuntimes()1
) {
898
1
      StaticRuntimes.push_back("cfi_diag");
899
1
      if (SanArgs.linkCXXRuntimes())
900
0
        StaticRuntimes.push_back("ubsan_standalone_cxx");
901
1
    }
902
1.69k
  }
903
1.70k
  if (SanArgs.needsStatsRt() && 
SanArgs.linkRuntimes()1
) {
904
1
    NonWholeStaticRuntimes.push_back("stats");
905
1
    RequiredSymbols.push_back("__sanitizer_stats_register");
906
1
  }
907
1.70k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsScudoRt()1.50k
&&
SanArgs.linkRuntimes()23
) {
908
23
    if (SanArgs.requiresMinimalRuntime()) {
909
3
      StaticRuntimes.push_back("scudo_minimal");
910
3
      if (SanArgs.linkCXXRuntimes())
911
0
        StaticRuntimes.push_back("scudo_cxx_minimal");
912
20
    } else {
913
20
      StaticRuntimes.push_back("scudo");
914
20
      if (SanArgs.linkCXXRuntimes())
915
0
        StaticRuntimes.push_back("scudo_cxx");
916
20
    }
917
23
  }
918
1.70k
}
919
920
// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
921
// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
922
bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
923
1.75k
                                 ArgStringList &CmdArgs) {
924
1.75k
  SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
925
1.75k
      NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
926
1.75k
  collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
927
1.75k
                           NonWholeStaticRuntimes, HelperStaticRuntimes,
928
1.75k
                           RequiredSymbols);
929
930
1.75k
  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
931
  // Inject libfuzzer dependencies.
932
1.75k
  if (SanArgs.needsFuzzer() && 
SanArgs.linkRuntimes()7
&&
933
1.75k
      
!Args.hasArg(options::OPT_shared)7
) {
934
935
7
    addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
936
7
    if (SanArgs.needsFuzzerInterceptors())
937
7
      addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
938
7
                          true);
939
7
    if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) {
940
7
      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
941
7
                                 
!Args.hasArg(options::OPT_static)2
;
942
7
      if (OnlyLibstdcxxStatic)
943
2
        CmdArgs.push_back("-Bstatic");
944
7
      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
945
7
      if (OnlyLibstdcxxStatic)
946
2
        CmdArgs.push_back("-Bdynamic");
947
7
    }
948
7
  }
949
950
1.75k
  for (auto RT : SharedRuntimes)
951
47
    addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
952
1.75k
  for (auto RT : HelperStaticRuntimes)
953
117
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
954
1.75k
  bool AddExportDynamic = false;
955
1.75k
  for (auto RT : StaticRuntimes) {
956
310
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
957
310
    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
958
310
  }
959
1.75k
  for (auto RT : NonWholeStaticRuntimes) {
960
12
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
961
12
    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
962
12
  }
963
1.75k
  for (auto S : RequiredSymbols) {
964
12
    CmdArgs.push_back("-u");
965
12
    CmdArgs.push_back(Args.MakeArgString(S));
966
12
  }
967
  // If there is a static runtime with no dynamic list, force all the symbols
968
  // to be dynamic to be sure we export sanitizer interface functions.
969
1.75k
  if (AddExportDynamic)
970
291
    CmdArgs.push_back("--export-dynamic");
971
972
1.75k
  if (SanArgs.hasCrossDsoCfi() && 
!AddExportDynamic4
)
973
2
    CmdArgs.push_back("--export-dynamic-symbol=__cfi_check");
974
975
1.75k
  return !StaticRuntimes.empty() || 
!NonWholeStaticRuntimes.empty()1.45k
;
976
1.75k
}
977
978
1.72k
bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) {
979
1.72k
  if (Args.hasArg(options::OPT_shared))
980
49
    return false;
981
982
1.67k
  if (TC.getXRayArgs().needsXRayRt()) {
983
2
    CmdArgs.push_back("-whole-archive");
984
2
    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray"));
985
2
    for (const auto &Mode : TC.getXRayArgs().modeList())
986
2
      CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode));
987
2
    CmdArgs.push_back("-no-whole-archive");
988
2
    return true;
989
2
  }
990
991
1.67k
  return false;
992
1.67k
}
993
994
2
void tools::linkXRayRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) {
995
2
  CmdArgs.push_back(getAsNeededOption(TC, false));
996
2
  CmdArgs.push_back("-lpthread");
997
2
  if (!TC.getTriple().isOSOpenBSD())
998
2
    CmdArgs.push_back("-lrt");
999
2
  CmdArgs.push_back("-lm");
1000
1001
2
  if (!TC.getTriple().isOSFreeBSD() &&
1002
2
      !TC.getTriple().isOSNetBSD() &&
1003
2
      !TC.getTriple().isOSOpenBSD())
1004
2
    CmdArgs.push_back("-ldl");
1005
2
}
1006
1007
4.58k
bool tools::areOptimizationsEnabled(const ArgList &Args) {
1008
  // Find the last -O arg and see if it is non-zero.
1009
4.58k
  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1010
200
    return !A->getOption().matches(options::OPT_O0);
1011
  // Defaults to -O0.
1012
4.38k
  return false;
1013
4.58k
}
1014
1015
const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args,
1016
                                  const InputInfo &Input,
1017
28
                                  const InputInfo &Output) {
1018
28
  auto AddPostfix = [JA](auto &F) {
1019
26
    if (JA.getOffloadingDeviceKind() == Action::OFK_HIP)
1020
0
      F += (Twine("_") + JA.getOffloadingArch()).str();
1021
26
    F += ".dwo";
1022
26
  };
1023
28
  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
1024
7
    if (StringRef(A->getValue()) == "single")
1025
2
      return Args.MakeArgString(Output.getFilename());
1026
1027
26
  Arg *FinalOutput = Args.getLastArg(options::OPT_o);
1028
26
  if (FinalOutput && 
Args.hasArg(options::OPT_c)4
) {
1029
2
    SmallString<128> T(FinalOutput->getValue());
1030
2
    llvm::sys::path::remove_filename(T);
1031
2
    llvm::sys::path::append(T, llvm::sys::path::stem(FinalOutput->getValue()));
1032
2
    AddPostfix(T);
1033
2
    return Args.MakeArgString(T);
1034
24
  } else {
1035
    // Use the compilation dir.
1036
24
    Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
1037
24
                             options::OPT_fdebug_compilation_dir_EQ);
1038
24
    SmallString<128> T(A ? 
A->getValue()0
: "");
1039
24
    SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
1040
24
    AddPostfix(F);
1041
24
    T += F;
1042
24
    return Args.MakeArgString(T);
1043
24
  }
1044
26
}
1045
1046
void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
1047
                           const JobAction &JA, const ArgList &Args,
1048
1
                           const InputInfo &Output, const char *OutFile) {
1049
1
  ArgStringList ExtractArgs;
1050
1
  ExtractArgs.push_back("--extract-dwo");
1051
1052
1
  ArgStringList StripArgs;
1053
1
  StripArgs.push_back("--strip-dwo");
1054
1055
  // Grabbing the output of the earlier compile step.
1056
1
  StripArgs.push_back(Output.getFilename());
1057
1
  ExtractArgs.push_back(Output.getFilename());
1058
1
  ExtractArgs.push_back(OutFile);
1059
1060
1
  const char *Exec =
1061
1
      Args.MakeArgString(TC.GetProgramPath(CLANG_DEFAULT_OBJCOPY));
1062
1
  InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
1063
1064
  // First extract the dwo sections.
1065
1
  C.addCommand(std::make_unique<Command>(JA, T,
1066
1
                                         ResponseFileSupport::AtFileCurCP(),
1067
1
                                         Exec, ExtractArgs, II, Output));
1068
1069
  // Then remove them from the original .o file.
1070
1
  C.addCommand(std::make_unique<Command>(
1071
1
      JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II, Output));
1072
1
}
1073
1074
// Claim options we don't want to warn if they are unused. We do this for
1075
// options that build systems might add but are unused when assembling or only
1076
// running the preprocessor for example.
1077
44.0k
void tools::claimNoWarnArgs(const ArgList &Args) {
1078
  // Don't warn about unused -f(no-)?lto.  This can happen when we're
1079
  // preprocessing, precompiling or assembling.
1080
44.0k
  Args.ClaimAllArgs(options::OPT_flto_EQ);
1081
44.0k
  Args.ClaimAllArgs(options::OPT_flto);
1082
44.0k
  Args.ClaimAllArgs(options::OPT_fno_lto);
1083
44.0k
}
1084
1085
43.0k
Arg *tools::getLastProfileUseArg(const ArgList &Args) {
1086
43.0k
  auto *ProfileUseArg = Args.getLastArg(
1087
43.0k
      options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
1088
43.0k
      options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
1089
43.0k
      options::OPT_fno_profile_instr_use);
1090
1091
43.0k
  if (ProfileUseArg &&
1092
43.0k
      
ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use)48
)
1093
4
    ProfileUseArg = nullptr;
1094
1095
43.0k
  return ProfileUseArg;
1096
43.0k
}
1097
1098
43.3k
Arg *tools::getLastProfileSampleUseArg(const ArgList &Args) {
1099
43.3k
  auto *ProfileSampleUseArg = Args.getLastArg(
1100
43.3k
      options::OPT_fprofile_sample_use, options::OPT_fprofile_sample_use_EQ,
1101
43.3k
      options::OPT_fauto_profile, options::OPT_fauto_profile_EQ,
1102
43.3k
      options::OPT_fno_profile_sample_use, options::OPT_fno_auto_profile);
1103
1104
43.3k
  if (ProfileSampleUseArg &&
1105
43.3k
      
(10
ProfileSampleUseArg->getOption().matches(
1106
10
           options::OPT_fno_profile_sample_use) ||
1107
10
       
ProfileSampleUseArg->getOption().matches(options::OPT_fno_auto_profile)8
))
1108
2
    return nullptr;
1109
1110
43.3k
  return Args.getLastArg(options::OPT_fprofile_sample_use_EQ,
1111
43.3k
                         options::OPT_fauto_profile_EQ);
1112
43.3k
}
1113
1114
/// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
1115
/// smooshes them together with platform defaults, to decide whether
1116
/// this compile should be using PIC mode or not. Returns a tuple of
1117
/// (RelocationModel, PICLevel, IsPIE).
1118
std::tuple<llvm::Reloc::Model, unsigned, bool>
1119
44.6k
tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
1120
44.6k
  const llvm::Triple &EffectiveTriple = ToolChain.getEffectiveTriple();
1121
44.6k
  const llvm::Triple &Triple = ToolChain.getTriple();
1122
1123
44.6k
  bool PIE = ToolChain.isPIEDefault(Args);
1124
44.6k
  bool PIC = PIE || 
ToolChain.isPICDefault()44.0k
;
1125
  // The Darwin/MachO default to use PIC does not apply when using -static.
1126
44.6k
  if (Triple.isOSBinFormatMachO() && 
Args.hasArg(options::OPT_static)16.6k
)
1127
26
    PIE = PIC = false;
1128
44.6k
  bool IsPICLevelTwo = PIC;
1129
1130
44.6k
  bool KernelOrKext =
1131
44.6k
      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
1132
1133
  // Android-specific defaults for PIC/PIE
1134
44.6k
  if (Triple.isAndroid()) {
1135
230
    switch (Triple.getArch()) {
1136
90
    case llvm::Triple::arm:
1137
90
    case llvm::Triple::armeb:
1138
92
    case llvm::Triple::thumb:
1139
92
    case llvm::Triple::thumbeb:
1140
146
    case llvm::Triple::aarch64:
1141
146
    case llvm::Triple::mips:
1142
180
    case llvm::Triple::mipsel:
1143
180
    case llvm::Triple::mips64:
1144
200
    case llvm::Triple::mips64el:
1145
200
      PIC = true; // "-fpic"
1146
200
      break;
1147
1148
15
    case llvm::Triple::x86:
1149
30
    case llvm::Triple::x86_64:
1150
30
      PIC = true; // "-fPIC"
1151
30
      IsPICLevelTwo = true;
1152
30
      break;
1153
1154
0
    default:
1155
0
      break;
1156
230
    }
1157
230
  }
1158
1159
  // OpenBSD-specific defaults for PIE
1160
44.6k
  if (Triple.isOSOpenBSD()) {
1161
127
    switch (ToolChain.getArch()) {
1162
12
    case llvm::Triple::arm:
1163
21
    case llvm::Triple::aarch64:
1164
33
    case llvm::Triple::mips64:
1165
45
    case llvm::Triple::mips64el:
1166
84
    case llvm::Triple::x86:
1167
103
    case llvm::Triple::x86_64:
1168
103
      IsPICLevelTwo = false; // "-fpie"
1169
103
      break;
1170
1171
4
    case llvm::Triple::ppc:
1172
17
    case llvm::Triple::sparcv9:
1173
17
      IsPICLevelTwo = true; // "-fPIE"
1174
17
      break;
1175
1176
7
    default:
1177
7
      break;
1178
127
    }
1179
127
  }
1180
1181
  // AMDGPU-specific defaults for PIC.
1182
44.6k
  if (Triple.getArch() == llvm::Triple::amdgcn)
1183
198
    PIC = true;
1184
1185
  // The last argument relating to either PIC or PIE wins, and no
1186
  // other argument is used. If the last argument is any flavor of the
1187
  // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
1188
  // option implicitly enables PIC at the same level.
1189
44.6k
  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
1190
44.6k
                                    options::OPT_fpic, options::OPT_fno_pic,
1191
44.6k
                                    options::OPT_fPIE, options::OPT_fno_PIE,
1192
44.6k
                                    options::OPT_fpie, options::OPT_fno_pie);
1193
44.6k
  if (Triple.isOSWindows() && 
!Triple.isOSCygMing()8.43k
&&
LastPICArg8.32k
&&
1194
44.6k
      LastPICArg == Args.getLastArg(options::OPT_fPIC, options::OPT_fpic,
1195
32
                                    options::OPT_fPIE, options::OPT_fpie)) {
1196
16
    ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1197
16
        << LastPICArg->getSpelling() << Triple.str();
1198
16
    if (Triple.getArch() == llvm::Triple::x86_64)
1199
8
      return std::make_tuple(llvm::Reloc::PIC_, 2U, false);
1200
8
    return std::make_tuple(llvm::Reloc::Static, 0U, false);
1201
16
  }
1202
1203
  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
1204
  // is forced, then neither PIC nor PIE flags will have no effect.
1205
44.5k
  if (!ToolChain.isPICDefaultForced()) {
1206
19.8k
    if (LastPICArg) {
1207
416
      Option O = LastPICArg->getOption();
1208
416
      if (O.matches(options::OPT_fPIC) || 
O.matches(options::OPT_fpic)355
||
1209
416
          
O.matches(options::OPT_fPIE)333
||
O.matches(options::OPT_fpie)318
) {
1210
112
        PIE = O.matches(options::OPT_fPIE) || 
O.matches(options::OPT_fpie)97
;
1211
112
        PIC =
1212
112
            PIE || 
O.matches(options::OPT_fPIC)83
||
O.matches(options::OPT_fpic)22
;
1213
112
        IsPICLevelTwo =
1214
112
            O.matches(options::OPT_fPIE) || 
O.matches(options::OPT_fPIC)97
;
1215
304
      } else {
1216
304
        PIE = PIC = false;
1217
304
        if (EffectiveTriple.isPS4CPU()) {
1218
20
          Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
1219
20
          StringRef Model = ModelArg ? 
ModelArg->getValue()4
:
""16
;
1220
20
          if (Model != "kernel") {
1221
16
            PIC = true;
1222
16
            ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
1223
16
                << LastPICArg->getSpelling();
1224
16
          }
1225
20
        }
1226
304
      }
1227
416
    }
1228
19.8k
  }
1229
1230
  // Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
1231
  // PIC level would've been set to level 1, force it back to level 2 PIC
1232
  // instead.
1233
44.5k
  if (PIC && 
(26.0k
Triple.isOSDarwin()26.0k
||
EffectiveTriple.isPS4CPU()9.48k
))
1234
16.7k
    IsPICLevelTwo |= ToolChain.isPICDefault();
1235
1236
  // This kernel flags are a trump-card: they will disable PIC/PIE
1237
  // generation, independent of the argument order.
1238
44.5k
  if (KernelOrKext &&
1239
44.5k
      
(27
(27
!EffectiveTriple.isiOS()27
||
EffectiveTriple.isOSVersionLT(6)8
) &&
1240
27
       
!EffectiveTriple.isWatchOS()23
))
1241
22
    PIC = PIE = false;
1242
1243
44.5k
  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
1244
    // This is a very special mode. It trumps the other modes, almost no one
1245
    // uses it, and it isn't even valid on any OS but Darwin.
1246
8
    if (!Triple.isOSDarwin())
1247
2
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1248
2
          << A->getSpelling() << Triple.str();
1249
1250
    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
1251
1252
    // Only a forced PIC mode can cause the actual compile to have PIC defines
1253
    // etc., no flags are sufficient. This behavior was selected to closely
1254
    // match that of llvm-gcc and Apple GCC before that.
1255
8
    PIC = ToolChain.isPICDefault() && 
ToolChain.isPICDefaultForced()7
;
1256
1257
8
    return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 
2U3
:
0U5
, false);
1258
8
  }
1259
1260
44.5k
  bool EmbeddedPISupported;
1261
44.5k
  switch (Triple.getArch()) {
1262
1.84k
    case llvm::Triple::arm:
1263
1.99k
    case llvm::Triple::armeb:
1264
2.05k
    case llvm::Triple::thumb:
1265
2.07k
    case llvm::Triple::thumbeb:
1266
2.07k
      EmbeddedPISupported = true;
1267
2.07k
      break;
1268
42.4k
    default:
1269
42.4k
      EmbeddedPISupported = false;
1270
42.4k
      break;
1271
44.5k
  }
1272
1273
44.5k
  bool ROPI = false, RWPI = false;
1274
44.5k
  Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
1275
44.5k
  if (LastROPIArg && 
LastROPIArg->getOption().matches(options::OPT_fropi)19
) {
1276
19
    if (!EmbeddedPISupported)
1277
2
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1278
2
          << LastROPIArg->getSpelling() << Triple.str();
1279
19
    ROPI = true;
1280
19
  }
1281
44.5k
  Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
1282
44.5k
  if (LastRWPIArg && 
LastRWPIArg->getOption().matches(options::OPT_frwpi)14
) {
1283
14
    if (!EmbeddedPISupported)
1284
2
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1285
2
          << LastRWPIArg->getSpelling() << Triple.str();
1286
14
    RWPI = true;
1287
14
  }
1288
1289
  // ROPI and RWPI are not compatible with PIC or PIE.
1290
44.5k
  if ((ROPI || 
RWPI44.5k
) &&
(26
PIC26
||
PIE23
))
1291
3
    ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
1292
1293
44.5k
  if (Triple.isMIPS()) {
1294
1.01k
    StringRef CPUName;
1295
1.01k
    StringRef ABIName;
1296
1.01k
    mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1297
    // When targeting the N64 ABI, PIC is the default, except in the case
1298
    // when the -mno-abicalls option is used. In that case we exit
1299
    // at next check regardless of PIC being set below.
1300
1.01k
    if (ABIName == "n64")
1301
282
      PIC = true;
1302
    // When targettng MIPS with -mno-abicalls, it's always static.
1303
1.01k
    if(Args.hasArg(options::OPT_mno_abicalls))
1304
77
      return std::make_tuple(llvm::Reloc::Static, 0U, false);
1305
    // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot,
1306
    // does not use PIC level 2 for historical reasons.
1307
936
    IsPICLevelTwo = false;
1308
936
  }
1309
1310
44.4k
  if (PIC)
1311
26.1k
    return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 
2U25.5k
:
1U634
, PIE);
1312
1313
18.3k
  llvm::Reloc::Model RelocM = llvm::Reloc::Static;
1314
18.3k
  if (ROPI && 
RWPI17
)
1315
6
    RelocM = llvm::Reloc::ROPI_RWPI;
1316
18.3k
  else if (ROPI)
1317
11
    RelocM = llvm::Reloc::ROPI;
1318
18.3k
  else if (RWPI)
1319
6
    RelocM = llvm::Reloc::RWPI;
1320
1321
18.3k
  return std::make_tuple(RelocM, 0U, false);
1322
44.4k
}
1323
1324
// `-falign-functions` indicates that the functions should be aligned to a
1325
// 16-byte boundary.
1326
//
1327
// `-falign-functions=1` is the same as `-fno-align-functions`.
1328
//
1329
// The scalar `n` in `-falign-functions=n` must be an integral value between
1330
// [0, 65536].  If the value is not a power-of-two, it will be rounded up to
1331
// the nearest power-of-two.
1332
//
1333
// If we return `0`, the frontend will default to the backend's preferred
1334
// alignment.
1335
//
1336
// NOTE: icc only allows values between [0, 4096].  icc uses `-falign-functions`
1337
// to mean `-falign-functions=16`.  GCC defaults to the backend's preferred
1338
// alignment.  For unaligned functions, we default to the backend's preferred
1339
// alignment.
1340
unsigned tools::ParseFunctionAlignment(const ToolChain &TC,
1341
43.1k
                                       const ArgList &Args) {
1342
43.1k
  const Arg *A = Args.getLastArg(options::OPT_falign_functions,
1343
43.1k
                                 options::OPT_falign_functions_EQ,
1344
43.1k
                                 options::OPT_fno_align_functions);
1345
43.1k
  if (!A || 
A->getOption().matches(options::OPT_fno_align_functions)8
)
1346
43.1k
    return 0;
1347
1348
7
  if (A->getOption().matches(options::OPT_falign_functions))
1349
1
    return 0;
1350
1351
6
  unsigned Value = 0;
1352
6
  if (StringRef(A->getValue()).getAsInteger(10, Value) || 
Value > 655365
)
1353
2
    TC.getDriver().Diag(diag::err_drv_invalid_int_value)
1354
2
        << A->getAsString(Args) << A->getValue();
1355
6
  return Value ? 
llvm::Log2_32_Ceil(std::min(Value, 65536u))5
:
Value1
;
1356
7
}
1357
1358
unsigned tools::ParseDebugDefaultVersion(const ToolChain &TC,
1359
43.5k
                                         const ArgList &Args) {
1360
43.5k
  const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version);
1361
1362
43.5k
  if (!A)
1363
43.5k
    return 0;
1364
1365
15
  unsigned Value = 0;
1366
15
  if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 5 ||
1367
15
      Value < 2)
1368
0
    TC.getDriver().Diag(diag::err_drv_invalid_int_value)
1369
0
        << A->getAsString(Args) << A->getValue();
1370
15
  return Value;
1371
43.5k
}
1372
1373
void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
1374
220
                             ArgStringList &CmdArgs) {
1375
220
  llvm::Reloc::Model RelocationModel;
1376
220
  unsigned PICLevel;
1377
220
  bool IsPIE;
1378
220
  std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args);
1379
1380
220
  if (RelocationModel != llvm::Reloc::Static)
1381
36
    CmdArgs.push_back("-KPIC");
1382
220
}
1383
1384
/// Determine whether Objective-C automated reference counting is
1385
/// enabled.
1386
46.7k
bool tools::isObjCAutoRefCount(const ArgList &Args) {
1387
46.7k
  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
1388
46.7k
}
1389
1390
enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
1391
1392
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
1393
5.19k
                                const ArgList &Args) {
1394
5.19k
  if (Args.hasArg(options::OPT_static_libgcc) ||
1395
5.19k
      
Args.hasArg(options::OPT_static)5.17k
||
Args.hasArg(options::OPT_static_pie)5.12k
)
1396
74
    return LibGccType::StaticLibGcc;
1397
5.11k
  if (Args.hasArg(options::OPT_shared_libgcc))
1398
10
    return LibGccType::SharedLibGcc;
1399
  // The Android NDK only provides libunwind.a, not libunwind.so.
1400
5.10k
  if (TC.getTriple().isAndroid())
1401
288
    return LibGccType::StaticLibGcc;
1402
  // For MinGW, don't imply a shared libgcc here, we only want to return
1403
  // SharedLibGcc if that was explicitly requested.
1404
4.81k
  if (D.CCCIsCXX() && 
!TC.getTriple().isOSCygMing()119
)
1405
117
    return LibGccType::SharedLibGcc;
1406
4.70k
  return LibGccType::UnspecifiedLibGcc;
1407
4.81k
}
1408
1409
// Gcc adds libgcc arguments in various ways:
1410
//
1411
// gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
1412
// g++ <none>:                       -lgcc_s               -lgcc
1413
// gcc shared:                       -lgcc_s               -lgcc
1414
// g++ shared:                       -lgcc_s               -lgcc
1415
// gcc static:     -lgcc             -lgcc_eh
1416
// g++ static:     -lgcc             -lgcc_eh
1417
// gcc static-pie: -lgcc             -lgcc_eh
1418
// g++ static-pie: -lgcc             -lgcc_eh
1419
//
1420
// Also, certain targets need additional adjustments.
1421
1422
static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
1423
2.99k
                             ArgStringList &CmdArgs, const ArgList &Args) {
1424
2.99k
  ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
1425
  // Targets that don't use unwind libraries.
1426
2.99k
  if ((TC.getTriple().isAndroid() && 
UNW == ToolChain::UNW_Libgcc298
) ||
1427
2.99k
      TC.getTriple().isOSIAMCU() || 
TC.getTriple().isOSBinFormatWasm()2.98k
||
1428
2.99k
      
UNW == ToolChain::UNW_None2.95k
)
1429
323
    return;
1430
1431
2.67k
  LibGccType LGT = getLibGccType(TC, D, Args);
1432
2.67k
  bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
1433
2.67k
                  
!TC.getTriple().isAndroid()2.27k
&&
1434
2.67k
                  
!TC.getTriple().isOSCygMing()2.27k
&&
!TC.getTriple().isOSAIX()2.27k
;
1435
2.67k
  if (AsNeeded)
1436
2.24k
    CmdArgs.push_back(getAsNeededOption(TC, true));
1437
1438
2.67k
  switch (UNW) {
1439
0
  case ToolChain::UNW_None:
1440
0
    return;
1441
2.31k
  case ToolChain::UNW_Libgcc: {
1442
2.31k
    if (LGT == LibGccType::StaticLibGcc)
1443
24
      CmdArgs.push_back("-lgcc_eh");
1444
2.29k
    else
1445
2.29k
      CmdArgs.push_back("-lgcc_s");
1446
2.31k
    break;
1447
0
  }
1448
357
  case ToolChain::UNW_CompilerRT:
1449
357
    if (TC.getTriple().isOSAIX()) {
1450
      // AIX only has libunwind as a shared library. So do not pass
1451
      // anything in if -static is specified.
1452
45
      if (LGT != LibGccType::StaticLibGcc)
1453
42
        CmdArgs.push_back("-lunwind");
1454
312
    } else if (LGT == LibGccType::StaticLibGcc) {
1455
302
      CmdArgs.push_back("-l:libunwind.a");
1456
302
    } else 
if (10
TC.getTriple().isOSCygMing()10
) {
1457
6
      if (LGT == LibGccType::SharedLibGcc)
1458
2
        CmdArgs.push_back("-l:libunwind.dll.a");
1459
4
      else
1460
        // Let the linker choose between libunwind.dll.a and libunwind.a
1461
        // depending on what's available, and depending on the -static flag
1462
4
        CmdArgs.push_back("-lunwind");
1463
6
    } else {
1464
4
      CmdArgs.push_back("-l:libunwind.so");
1465
4
    }
1466
357
    break;
1467
2.67k
  }
1468
1469
2.67k
  if (AsNeeded)
1470
2.24k
    CmdArgs.push_back(getAsNeededOption(TC, false));
1471
2.67k
}
1472
1473
static void AddLibgcc(const ToolChain &TC, const Driver &D,
1474
2.51k
                      ArgStringList &CmdArgs, const ArgList &Args) {
1475
2.51k
  LibGccType LGT = getLibGccType(TC, D, Args);
1476
2.51k
  if (LGT != LibGccType::SharedLibGcc)
1477
2.46k
    CmdArgs.push_back("-lgcc");
1478
2.51k
  AddUnwindLibrary(TC, D, CmdArgs, Args);
1479
2.51k
  if (LGT == LibGccType::SharedLibGcc)
1480
56
    CmdArgs.push_back("-lgcc");
1481
2.51k
}
1482
1483
void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
1484
3.37k
                           ArgStringList &CmdArgs, const ArgList &Args) {
1485
  // Make use of compiler-rt if --rtlib option is used
1486
3.37k
  ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
1487
1488
3.37k
  switch (RLT) {
1489
480
  case ToolChain::RLT_CompilerRT:
1490
480
    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
1491
480
    AddUnwindLibrary(TC, D, CmdArgs, Args);
1492
480
    break;
1493
2.89k
  case ToolChain::RLT_Libgcc:
1494
    // Make sure libgcc is not used under MSVC environment by default
1495
2.89k
    if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1496
      // Issue error diagnostic if libgcc is explicitly specified
1497
      // through command line as --rtlib option argument.
1498
377
      if (Args.hasArg(options::OPT_rtlib_EQ)) {
1499
5
        TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
1500
5
            << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
1501
5
      }
1502
377
    } else
1503
2.51k
      AddLibgcc(TC, D, CmdArgs, Args);
1504
2.89k
    break;
1505
3.37k
  }
1506
1507
  // On Android, the unwinder uses dl_iterate_phdr (or one of
1508
  // dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
1509
  // statically-linked executables, these functions come from libc.a instead.
1510
3.37k
  if (TC.getTriple().isAndroid() && 
!Args.hasArg(options::OPT_static)298
&&
1511
3.37k
      
!Args.hasArg(options::OPT_static_pie)288
)
1512
288
    CmdArgs.push_back("-ldl");
1513
3.37k
}
1514
1515
SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
1516
                                         const InputInfo &Output,
1517
                                         const InputInfo &Input,
1518
46.8k
                                         const Driver &D) {
1519
46.8k
  const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ);
1520
46.8k
  if (!A)
1521
46.8k
    return {};
1522
1523
16
  StringRef SaveStats = A->getValue();
1524
16
  SmallString<128> StatsFile;
1525
16
  if (SaveStats == "obj" && 
Output.isFilename()4
) {
1526
4
    StatsFile.assign(Output.getFilename());
1527
4
    llvm::sys::path::remove_filename(StatsFile);
1528
12
  } else if (SaveStats != "cwd") {
1529
1
    D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
1530
1
    return {};
1531
1
  }
1532
1533
15
  StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
1534
15
  llvm::sys::path::append(StatsFile, BaseName);
1535
15
  llvm::sys::path::replace_extension(StatsFile, "stats");
1536
15
  return StatsFile;
1537
16
}
1538
1539
void tools::addMultilibFlag(bool Enabled, const char *const Flag,
1540
3.15k
                            Multilib::flags_list &Flags) {
1541
3.15k
  Flags.push_back(std::string(Enabled ? 
"+"809
:
"-"2.34k
) + Flag);
1542
3.15k
}
1543
1544
void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,
1545
37.9k
                                  ArgStringList &CmdArgs, bool IsLTO) {
1546
37.9k
  auto addArg = [&, IsLTO](const Twine &Arg) {
1547
25
    if (IsLTO) {
1548
4
      CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
1549
21
    } else {
1550
21
      CmdArgs.push_back("-mllvm");
1551
21
      CmdArgs.push_back(Args.MakeArgString(Arg));
1552
21
    }
1553
25
  };
1554
1555
37.9k
  if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) {
1556
5
    addArg(Twine("-x86-branches-within-32B-boundaries"));
1557
5
  }
1558
37.9k
  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) {
1559
6
    StringRef Value = A->getValue();
1560
6
    unsigned Boundary;
1561
6
    if (Value.getAsInteger(10, Boundary) || Boundary < 16 ||
1562
6
        
!llvm::isPowerOf2_64(Boundary)4
) {
1563
2
      D.Diag(diag::err_drv_invalid_argument_to_option)
1564
2
          << Value << A->getOption().getName();
1565
4
    } else {
1566
4
      addArg("-x86-align-branch-boundary=" + Twine(Boundary));
1567
4
    }
1568
6
  }
1569
37.9k
  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) {
1570
11
    std::string AlignBranch;
1571
39
    for (StringRef T : A->getValues()) {
1572
39
      if (T != "fused" && 
T != "jcc"28
&&
T != "jmp"19
&&
T != "call"10
&&
1573
39
          
T != "ret"8
&&
T != "indirect"6
)
1574
4
        D.Diag(diag::err_drv_invalid_malign_branch_EQ)
1575
4
            << T << "fused, jcc, jmp, call, ret, indirect";
1576
39
      if (!AlignBranch.empty())
1577
28
        AlignBranch += '+';
1578
39
      AlignBranch += T;
1579
39
    }
1580
11
    addArg("-x86-align-branch=" + Twine(AlignBranch));
1581
11
  }
1582
37.9k
  if (const Arg *A = Args.getLastArg(options::OPT_mpad_max_prefix_size_EQ)) {
1583
5
    StringRef Value = A->getValue();
1584
5
    unsigned PrefixSize;
1585
5
    if (Value.getAsInteger(10, PrefixSize)) {
1586
0
      D.Diag(diag::err_drv_invalid_argument_to_option)
1587
0
          << Value << A->getOption().getName();
1588
5
    } else {
1589
5
      addArg("-x86-pad-max-prefix-size=" + Twine(PrefixSize));
1590
5
    }
1591
5
  }
1592
37.9k
}
1593
1594
/// SDLSearch: Search for Static Device Library
1595
/// The search for SDL bitcode files is consistent with how static host
1596
/// libraries are discovered. That is, the -l option triggers a search for
1597
/// files in a set of directories called the LINKPATH. The host library search
1598
/// procedure looks for a specific filename in the LINKPATH.  The filename for
1599
/// a host library is lib<libname>.a or lib<libname>.so. For SDLs, there is an
1600
/// ordered-set of filenames that are searched. We call this ordered-set of
1601
/// filenames as SEARCH-ORDER. Since an SDL can either be device-type specific,
1602
/// architecture specific, or generic across all architectures, a naming
1603
/// convention and search order is used where the file name embeds the
1604
/// architecture name <arch-name> (nvptx or amdgcn) and the GPU device type
1605
/// <device-name> such as sm_30 and gfx906. <device-name> is absent in case of
1606
/// device-independent SDLs. To reduce congestion in host library directories,
1607
/// the search first looks for files in the “libdevice” subdirectory. SDLs that
1608
/// are bc files begin with the prefix “lib”.
1609
///
1610
/// Machine-code SDLs can also be managed as an archive (*.a file). The
1611
/// convention has been to use the prefix “lib”. To avoid confusion with host
1612
/// archive libraries, we use prefix "libbc-" for the bitcode SDL archives.
1613
///
1614
bool tools::SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs,
1615
                      llvm::opt::ArgStringList &CC1Args,
1616
                      SmallVector<std::string, 8> LibraryPaths, std::string Lib,
1617
                      StringRef Arch, StringRef Target, bool isBitCodeSDL,
1618
0
                      bool postClangLink) {
1619
0
  SmallVector<std::string, 12> SDLs;
1620
1621
0
  std::string LibDeviceLoc = "/libdevice";
1622
0
  std::string LibBcPrefix = "/libbc-";
1623
0
  std::string LibPrefix = "/lib";
1624
1625
0
  if (isBitCodeSDL) {
1626
    // SEARCH-ORDER for Bitcode SDLs:
1627
    //       libdevice/libbc-<libname>-<arch-name>-<device-type>.a
1628
    //       libbc-<libname>-<arch-name>-<device-type>.a
1629
    //       libdevice/libbc-<libname>-<arch-name>.a
1630
    //       libbc-<libname>-<arch-name>.a
1631
    //       libdevice/libbc-<libname>.a
1632
    //       libbc-<libname>.a
1633
    //       libdevice/lib<libname>-<arch-name>-<device-type>.bc
1634
    //       lib<libname>-<arch-name>-<device-type>.bc
1635
    //       libdevice/lib<libname>-<arch-name>.bc
1636
    //       lib<libname>-<arch-name>.bc
1637
    //       libdevice/lib<libname>.bc
1638
    //       lib<libname>.bc
1639
1640
0
    for (StringRef Base : {LibBcPrefix, LibPrefix}) {
1641
0
      const auto *Ext = Base.contains(LibBcPrefix) ? ".a" : ".bc";
1642
1643
0
      for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
1644
0
                          Twine(Lib + "-" + Arch).str(), Twine(Lib).str()}) {
1645
0
        SDLs.push_back(Twine(LibDeviceLoc + Base + Suffix + Ext).str());
1646
0
        SDLs.push_back(Twine(Base + Suffix + Ext).str());
1647
0
      }
1648
0
    }
1649
0
  } else {
1650
    // SEARCH-ORDER for Machine-code SDLs:
1651
    //    libdevice/lib<libname>-<arch-name>-<device-type>.a
1652
    //    lib<libname>-<arch-name>-<device-type>.a
1653
    //    libdevice/lib<libname>-<arch-name>.a
1654
    //    lib<libname>-<arch-name>.a
1655
1656
0
    const auto *Ext = ".a";
1657
1658
0
    for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
1659
0
                        Twine(Lib + "-" + Arch).str()}) {
1660
0
      SDLs.push_back(Twine(LibDeviceLoc + LibPrefix + Suffix + Ext).str());
1661
0
      SDLs.push_back(Twine(LibPrefix + Suffix + Ext).str());
1662
0
    }
1663
0
  }
1664
1665
  // The CUDA toolchain does not use a global device llvm-link before the LLVM
1666
  // backend generates ptx. So currently, the use of bitcode SDL for nvptx is
1667
  // only possible with post-clang-cc1 linking. Clang cc1 has a feature that
1668
  // will link libraries after clang compilation while the LLVM IR is still in
1669
  // memory. This utilizes a clang cc1 option called “-mlink-builtin-bitcode”.
1670
  // This is a clang -cc1 option that is generated by the clang driver. The
1671
  // option value must a full path to an existing file.
1672
0
  bool FoundSDL = false;
1673
0
  for (auto LPath : LibraryPaths) {
1674
0
    for (auto SDL : SDLs) {
1675
0
      auto FullName = Twine(LPath + SDL).str();
1676
0
      if (llvm::sys::fs::exists(FullName)) {
1677
0
        if (postClangLink)
1678
0
          CC1Args.push_back("-mlink-builtin-bitcode");
1679
0
        CC1Args.push_back(DriverArgs.MakeArgString(FullName));
1680
0
        FoundSDL = true;
1681
0
        break;
1682
0
      }
1683
0
    }
1684
0
    if (FoundSDL)
1685
0
      break;
1686
0
  }
1687
0
  return FoundSDL;
1688
0
}
1689
1690
/// Search if a user provided archive file lib<libname>.a exists in any of
1691
/// the library paths. If so, add a new command to clang-offload-bundler to
1692
/// unbundle this archive and create a temporary device specific archive. Name
1693
/// of this SDL is passed to the llvm-link (for amdgcn) or to the
1694
/// clang-nvlink-wrapper (for nvptx) commands by the driver.
1695
bool tools::GetSDLFromOffloadArchive(
1696
    Compilation &C, const Driver &D, const Tool &T, const JobAction &JA,
1697
    const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs,
1698
    llvm::opt::ArgStringList &CC1Args, SmallVector<std::string, 8> LibraryPaths,
1699
    StringRef Lib, StringRef Arch, StringRef Target, bool isBitCodeSDL,
1700
0
    bool postClangLink) {
1701
1702
  // We don't support bitcode archive bundles for nvptx
1703
0
  if (isBitCodeSDL && Arch.contains("nvptx"))
1704
0
    return false;
1705
1706
0
  bool FoundAOB = false;
1707
0
  SmallVector<std::string, 2> AOBFileNames;
1708
0
  std::string ArchiveOfBundles;
1709
0
  for (auto LPath : LibraryPaths) {
1710
0
    ArchiveOfBundles.clear();
1711
1712
0
    AOBFileNames.push_back(Twine(LPath + "/libdevice/lib" + Lib + ".a").str());
1713
0
    AOBFileNames.push_back(Twine(LPath + "/lib" + Lib + ".a").str());
1714
1715
0
    for (auto AOB : AOBFileNames) {
1716
0
      if (llvm::sys::fs::exists(AOB)) {
1717
0
        ArchiveOfBundles = AOB;
1718
0
        FoundAOB = true;
1719
0
        break;
1720
0
      }
1721
0
    }
1722
1723
0
    if (!FoundAOB)
1724
0
      continue;
1725
1726
0
    StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib";
1727
0
    std::string OutputLib = D.GetTemporaryPath(
1728
0
        Twine(Prefix + Lib + "-" + Arch + "-" + Target).str(), "a");
1729
1730
0
    C.addTempFile(C.getArgs().MakeArgString(OutputLib));
1731
1732
0
    ArgStringList CmdArgs;
1733
0
    SmallString<128> DeviceTriple;
1734
0
    DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind());
1735
0
    DeviceTriple += '-';
1736
0
    std::string NormalizedTriple = T.getToolChain().getTriple().normalize();
1737
0
    DeviceTriple += NormalizedTriple;
1738
0
    if (!Target.empty()) {
1739
0
      DeviceTriple += '-';
1740
0
      DeviceTriple += Target;
1741
0
    }
1742
1743
0
    std::string UnbundleArg("-unbundle");
1744
0
    std::string TypeArg("-type=a");
1745
0
    std::string InputArg("-inputs=" + ArchiveOfBundles);
1746
0
    std::string OffloadArg("-targets=" + std::string(DeviceTriple));
1747
0
    std::string OutputArg("-outputs=" + OutputLib);
1748
1749
0
    const char *UBProgram = DriverArgs.MakeArgString(
1750
0
        T.getToolChain().GetProgramPath("clang-offload-bundler"));
1751
1752
0
    ArgStringList UBArgs;
1753
0
    UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg));
1754
0
    UBArgs.push_back(C.getArgs().MakeArgString(TypeArg));
1755
0
    UBArgs.push_back(C.getArgs().MakeArgString(InputArg));
1756
0
    UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg));
1757
0
    UBArgs.push_back(C.getArgs().MakeArgString(OutputArg));
1758
1759
    // Add this flag to not exit from clang-offload-bundler if no compatible
1760
    // code object is found in heterogenous archive library.
1761
0
    std::string AdditionalArgs("-allow-missing-bundles");
1762
0
    UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs));
1763
1764
0
    C.addCommand(std::make_unique<Command>(
1765
0
        JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs,
1766
0
        InputInfo(&JA, C.getArgs().MakeArgString(OutputLib))));
1767
0
    if (postClangLink)
1768
0
      CC1Args.push_back("-mlink-builtin-bitcode");
1769
1770
0
    CC1Args.push_back(DriverArgs.MakeArgString(OutputLib));
1771
0
    break;
1772
0
  }
1773
1774
0
  return FoundAOB;
1775
0
}
1776
1777
// Wrapper function used by driver for adding SDLs during link phase.
1778
void tools::AddStaticDeviceLibsLinking(Compilation &C, const Tool &T,
1779
                                const JobAction &JA,
1780
                                const InputInfoList &Inputs,
1781
                                const llvm::opt::ArgList &DriverArgs,
1782
                                llvm::opt::ArgStringList &CC1Args,
1783
                                StringRef Arch, StringRef Target,
1784
0
                                bool isBitCodeSDL, bool postClangLink) {
1785
0
  AddStaticDeviceLibs(&C, &T, &JA, &Inputs, C.getDriver(), DriverArgs, CC1Args,
1786
0
                      Arch, Target, isBitCodeSDL, postClangLink);
1787
0
}
1788
1789
// Wrapper function used for post clang linking of bitcode SDLS for nvptx by
1790
// the CUDA toolchain.
1791
void tools::AddStaticDeviceLibsPostLinking(const Driver &D,
1792
                                const llvm::opt::ArgList &DriverArgs,
1793
                                llvm::opt::ArgStringList &CC1Args,
1794
                                StringRef Arch, StringRef Target,
1795
0
                                bool isBitCodeSDL, bool postClangLink) {
1796
0
  AddStaticDeviceLibs(nullptr, nullptr, nullptr, nullptr, D, DriverArgs,
1797
0
                      CC1Args, Arch, Target, isBitCodeSDL, postClangLink);
1798
0
}
1799
1800
// User defined Static Device Libraries(SDLs) can be passed to clang for
1801
// offloading GPU compilers. Like static host libraries, the use of a SDL is
1802
// specified with the -l command line option. The primary difference between
1803
// host and SDLs is the filenames for SDLs (refer SEARCH-ORDER for Bitcode SDLs
1804
// and SEARCH-ORDER for Machine-code SDLs for the naming convention).
1805
// SDLs are of following types:
1806
//
1807
// * Bitcode SDLs: They can either be a *.bc file or an archive of *.bc files.
1808
//           For NVPTX, these libraries are post-clang linked following each
1809
//           compilation. For AMDGPU, these libraries are linked one time
1810
//           during the application link phase.
1811
//
1812
// * Machine-code SDLs: They are archive files. For NVPTX, the archive members
1813
//           contain cubin for Nvidia GPUs and are linked one time during the
1814
//           link phase by the CUDA SDK linker called nvlink. For AMDGPU, the
1815
//           process for machine code SDLs is still in development. But they
1816
//           will be linked by the LLVM tool lld.
1817
//
1818
// * Bundled objects that contain both host and device codes: Bundled objects
1819
//           may also contain library code compiled from source. For NVPTX, the
1820
//           bundle contains cubin. For AMDGPU, the bundle contains bitcode.
1821
//
1822
// For Bitcode and Machine-code SDLs, current compiler toolchains hardcode the
1823
// inclusion of specific SDLs such as math libraries and the OpenMP device
1824
// library libomptarget.
1825
void tools::AddStaticDeviceLibs(Compilation *C, const Tool *T,
1826
                                const JobAction *JA,
1827
                                const InputInfoList *Inputs, const Driver &D,
1828
                                const llvm::opt::ArgList &DriverArgs,
1829
                                llvm::opt::ArgStringList &CC1Args,
1830
                                StringRef Arch, StringRef Target,
1831
0
                                bool isBitCodeSDL, bool postClangLink) {
1832
1833
0
  SmallVector<std::string, 8> LibraryPaths;
1834
  // Add search directories from LIBRARY_PATH env variable
1835
0
  llvm::Optional<std::string> LibPath =
1836
0
      llvm::sys::Process::GetEnv("LIBRARY_PATH");
1837
0
  if (LibPath) {
1838
0
    SmallVector<StringRef, 8> Frags;
1839
0
    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
1840
0
    llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
1841
0
    for (StringRef Path : Frags)
1842
0
      LibraryPaths.emplace_back(Path.trim());
1843
0
  }
1844
1845
  // Add directories from user-specified -L options
1846
0
  for (std::string Search_Dir : DriverArgs.getAllArgValues(options::OPT_L))
1847
0
    LibraryPaths.emplace_back(Search_Dir);
1848
1849
  // Add path to lib-debug folders
1850
0
  SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
1851
0
  llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
1852
0
  LibraryPaths.emplace_back(DefaultLibPath.c_str());
1853
1854
  // Build list of Static Device Libraries SDLs specified by -l option
1855
0
  llvm::SmallSet<std::string, 16> SDLNames;
1856
0
  static const StringRef HostOnlyArchives[] = {
1857
0
      "omp", "cudart", "m", "gcc", "gcc_s", "pthread", "hip_hcc"};
1858
0
  for (auto SDLName : DriverArgs.getAllArgValues(options::OPT_l)) {
1859
0
    if (!HostOnlyArchives->contains(SDLName)) {
1860
0
      SDLNames.insert(SDLName);
1861
0
    }
1862
0
  }
1863
1864
  // The search stops as soon as an SDL file is found. The driver then provides
1865
  // the full filename of the SDL to the llvm-link or clang-nvlink-wrapper
1866
  // command. If no SDL is found after searching each LINKPATH with
1867
  // SEARCH-ORDER, it is possible that an archive file lib<libname>.a exists
1868
  // and may contain bundled object files.
1869
0
  for (auto SDLName : SDLNames) {
1870
    // This is the only call to SDLSearch
1871
0
    if (!SDLSearch(D, DriverArgs, CC1Args, LibraryPaths, SDLName, Arch, Target,
1872
0
                   isBitCodeSDL, postClangLink)) {
1873
0
      GetSDLFromOffloadArchive(*C, D, *T, *JA, *Inputs, DriverArgs, CC1Args,
1874
0
                               LibraryPaths, SDLName, Arch, Target,
1875
0
                               isBitCodeSDL, postClangLink);
1876
0
    }
1877
0
  }
1878
0
}
1879
1880
static llvm::opt::Arg *
1881
265
getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args) {
1882
  // The last of -mcode-object-v3, -mno-code-object-v3 and
1883
  // -mcode-object-version=<version> wins.
1884
265
  return Args.getLastArg(options::OPT_mcode_object_v3_legacy,
1885
265
                         options::OPT_mno_code_object_v3_legacy,
1886
265
                         options::OPT_mcode_object_version_EQ);
1887
265
}
1888
1889
void tools::checkAMDGPUCodeObjectVersion(const Driver &D,
1890
78
                                         const llvm::opt::ArgList &Args) {
1891
78
  const unsigned MinCodeObjVer = 2;
1892
78
  const unsigned MaxCodeObjVer = 4;
1893
1894
  // Emit warnings for legacy options even if they are overridden.
1895
78
  if (Args.hasArg(options::OPT_mno_code_object_v3_legacy))
1896
4
    D.Diag(diag::warn_drv_deprecated_arg) << "-mno-code-object-v3"
1897
4
                                          << "-mcode-object-version=2";
1898
1899
78
  if (Args.hasArg(options::OPT_mcode_object_v3_legacy))
1900
4
    D.Diag(diag::warn_drv_deprecated_arg) << "-mcode-object-v3"
1901
4
                                          << "-mcode-object-version=3";
1902
1903
78
  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
1904
6
    if (CodeObjArg->getOption().getID() ==
1905
6
        options::OPT_mcode_object_version_EQ) {
1906
0
      unsigned CodeObjVer = MaxCodeObjVer;
1907
0
      auto Remnant =
1908
0
          StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
1909
0
      if (Remnant || CodeObjVer < MinCodeObjVer || CodeObjVer > MaxCodeObjVer)
1910
0
        D.Diag(diag::err_drv_invalid_int_value)
1911
0
            << CodeObjArg->getAsString(Args) << CodeObjArg->getValue();
1912
0
    }
1913
6
  }
1914
78
}
1915
1916
unsigned tools::getAMDGPUCodeObjectVersion(const Driver &D,
1917
21
                                           const llvm::opt::ArgList &Args) {
1918
21
  unsigned CodeObjVer = 4; // default
1919
21
  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
1920
6
    if (CodeObjArg->getOption().getID() ==
1921
6
        options::OPT_mno_code_object_v3_legacy) {
1922
2
      CodeObjVer = 2;
1923
4
    } else if (CodeObjArg->getOption().getID() ==
1924
4
               options::OPT_mcode_object_v3_legacy) {
1925
4
      CodeObjVer = 3;
1926
4
    } else {
1927
0
      StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
1928
0
    }
1929
6
  }
1930
21
  return CodeObjVer;
1931
21
}
1932
1933
bool tools::haveAMDGPUCodeObjectVersionArgument(
1934
166
    const Driver &D, const llvm::opt::ArgList &Args) {
1935
166
  return getAMDGPUCodeObjectArgument(D, Args) != nullptr;
1936
166
}
1937
1938
void tools::addMachineOutlinerArgs(const Driver &D,
1939
                                   const llvm::opt::ArgList &Args,
1940
                                   llvm::opt::ArgStringList &CmdArgs,
1941
43.2k
                                   const llvm::Triple &Triple, bool IsLTO) {
1942
43.2k
  auto addArg = [&, IsLTO](const Twine &Arg) {
1943
8
    if (IsLTO) {
1944
2
      CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
1945
6
    } else {
1946
6
      CmdArgs.push_back("-mllvm");
1947
6
      CmdArgs.push_back(Args.MakeArgString(Arg));
1948
6
    }
1949
8
  };
1950
1951
43.2k
  if (Arg *A = Args.getLastArg(options::OPT_moutline,
1952
43.2k
                               options::OPT_mno_outline)) {
1953
9
    if (A->getOption().matches(options::OPT_moutline)) {
1954
      // We only support -moutline in AArch64 and ARM targets right now. If
1955
      // we're not compiling for these, emit a warning and ignore the flag.
1956
      // Otherwise, add the proper mllvm flags.
1957
5
      if (!(Triple.isARM() || 
Triple.isThumb()2
||
1958
5
            
Triple.getArch() == llvm::Triple::aarch642
||
1959
5
            
Triple.getArch() == llvm::Triple::aarch64_321
)) {
1960
1
        D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
1961
4
      } else {
1962
4
        addArg(Twine("-enable-machine-outliner"));
1963
4
      }
1964
5
    } else {
1965
      // Disable all outlining behaviour.
1966
4
      addArg(Twine("-enable-machine-outliner=never"));
1967
4
    }
1968
9
  }
1969
43.2k
}
1970
1971
void tools::addOpenMPDeviceRTL(const Driver &D,
1972
                               const llvm::opt::ArgList &DriverArgs,
1973
                               llvm::opt::ArgStringList &CC1Args,
1974
                               StringRef BitcodeSuffix,
1975
0
                               const llvm::Triple &Triple) {
1976
0
  SmallVector<StringRef, 8> LibraryPaths;
1977
1978
  // Add path to clang lib / lib64 folder.
1979
0
  SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
1980
0
  llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
1981
0
  LibraryPaths.emplace_back(DefaultLibPath.c_str());
1982
1983
  // Add user defined library paths from LIBRARY_PATH.
1984
0
  llvm::Optional<std::string> LibPath =
1985
0
      llvm::sys::Process::GetEnv("LIBRARY_PATH");
1986
0
  if (LibPath) {
1987
0
    SmallVector<StringRef, 8> Frags;
1988
0
    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
1989
0
    llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
1990
0
    for (StringRef Path : Frags)
1991
0
      LibraryPaths.emplace_back(Path.trim());
1992
0
  }
1993
1994
0
  OptSpecifier LibomptargetBCPathOpt =
1995
0
      Triple.isAMDGCN() ? options::OPT_libomptarget_amdgcn_bc_path_EQ
1996
0
                        : options::OPT_libomptarget_nvptx_bc_path_EQ;
1997
1998
0
  StringRef ArchPrefix = Triple.isAMDGCN() ? "amdgcn" : "nvptx";
1999
0
  std::string LibOmpTargetName = "libomptarget-" + BitcodeSuffix.str() + ".bc";
2000
2001
  // First check whether user specifies bc library
2002
0
  if (const Arg *A = DriverArgs.getLastArg(LibomptargetBCPathOpt)) {
2003
0
    SmallString<128> LibOmpTargetFile(A->getValue());
2004
0
    if (llvm::sys::fs::exists(LibOmpTargetFile) &&
2005
0
        llvm::sys::fs::is_directory(LibOmpTargetFile)) {
2006
0
      llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2007
0
    }
2008
2009
0
    if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2010
0
      CC1Args.push_back("-mlink-builtin-bitcode");
2011
0
      CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2012
0
    } else {
2013
0
      D.Diag(diag::err_drv_omp_offload_target_bcruntime_not_found)
2014
0
          << LibOmpTargetFile;
2015
0
    }
2016
0
  } else {
2017
0
    bool FoundBCLibrary = false;
2018
2019
0
    for (StringRef LibraryPath : LibraryPaths) {
2020
0
      SmallString<128> LibOmpTargetFile(LibraryPath);
2021
0
      llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2022
0
      if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2023
0
        CC1Args.push_back("-mlink-builtin-bitcode");
2024
0
        CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2025
0
        FoundBCLibrary = true;
2026
0
        break;
2027
0
      }
2028
0
    }
2029
2030
0
    if (!FoundBCLibrary)
2031
0
      D.Diag(diag::err_drv_omp_offload_target_missingbcruntime)
2032
0
          << LibOmpTargetName << ArchPrefix;
2033
0
  }
2034
0
}