Coverage Report

Created: 2023-09-30 09:22

/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/CSKY.h"
13
#include "Arch/LoongArch.h"
14
#include "Arch/M68k.h"
15
#include "Arch/Mips.h"
16
#include "Arch/PPC.h"
17
#include "Arch/RISCV.h"
18
#include "Arch/Sparc.h"
19
#include "Arch/SystemZ.h"
20
#include "Arch/VE.h"
21
#include "Arch/X86.h"
22
#include "HIPAMD.h"
23
#include "Hexagon.h"
24
#include "MSP430.h"
25
#include "Solaris.h"
26
#include "clang/Basic/CharInfo.h"
27
#include "clang/Basic/LangOptions.h"
28
#include "clang/Basic/ObjCRuntime.h"
29
#include "clang/Basic/Version.h"
30
#include "clang/Config/config.h"
31
#include "clang/Driver/Action.h"
32
#include "clang/Driver/Compilation.h"
33
#include "clang/Driver/Driver.h"
34
#include "clang/Driver/DriverDiagnostic.h"
35
#include "clang/Driver/InputInfo.h"
36
#include "clang/Driver/Job.h"
37
#include "clang/Driver/Options.h"
38
#include "clang/Driver/SanitizerArgs.h"
39
#include "clang/Driver/ToolChain.h"
40
#include "clang/Driver/Util.h"
41
#include "clang/Driver/XRayArgs.h"
42
#include "llvm/ADT/STLExtras.h"
43
#include "llvm/ADT/SmallSet.h"
44
#include "llvm/ADT/SmallString.h"
45
#include "llvm/ADT/StringExtras.h"
46
#include "llvm/ADT/StringSwitch.h"
47
#include "llvm/ADT/Twine.h"
48
#include "llvm/BinaryFormat/Magic.h"
49
#include "llvm/Config/llvm-config.h"
50
#include "llvm/Option/Arg.h"
51
#include "llvm/Option/ArgList.h"
52
#include "llvm/Option/Option.h"
53
#include "llvm/Support/CodeGen.h"
54
#include "llvm/Support/Compression.h"
55
#include "llvm/Support/Debug.h"
56
#include "llvm/Support/ErrorHandling.h"
57
#include "llvm/Support/FileSystem.h"
58
#include "llvm/Support/Path.h"
59
#include "llvm/Support/Process.h"
60
#include "llvm/Support/Program.h"
61
#include "llvm/Support/ScopedPrinter.h"
62
#include "llvm/Support/Threading.h"
63
#include "llvm/Support/VirtualFileSystem.h"
64
#include "llvm/Support/YAMLParser.h"
65
#include "llvm/TargetParser/Host.h"
66
#include "llvm/TargetParser/TargetParser.h"
67
#include <optional>
68
69
using namespace clang::driver;
70
using namespace clang::driver::tools;
71
using namespace clang;
72
using namespace llvm::opt;
73
74
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
75
424
                               const StringRef PluginOptPrefix) {
76
424
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
77
2
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
78
2
                                         "-pass-remarks=" + A->getValue()));
79
80
424
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
81
2
    CmdArgs.push_back(Args.MakeArgString(
82
2
        Twine(PluginOptPrefix) + "-pass-remarks-missed=" + A->getValue()));
83
84
424
  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
85
2
    CmdArgs.push_back(Args.MakeArgString(
86
2
        Twine(PluginOptPrefix) + "-pass-remarks-analysis=" + A->getValue()));
87
424
}
88
89
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
90
                                 const llvm::Triple &Triple,
91
                                 const InputInfo &Input,
92
                                 const InputInfo &Output,
93
3
                                 const StringRef PluginOptPrefix) {
94
3
  StringRef Format = "yaml";
95
3
  if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
96
1
    Format = A->getValue();
97
98
3
  SmallString<128> F;
99
3
  const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
100
3
  if (A)
101
1
    F = A->getValue();
102
2
  else if (Output.isFilename())
103
2
    F = Output.getFilename();
104
105
3
  assert(!F.empty() && "Cannot determine remarks output name.");
106
  // Append "opt.ld.<format>" to the end of the file name.
107
3
  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
108
3
                                       "opt-remarks-filename=" + F +
109
3
                                       ".opt.ld." + Format));
110
111
3
  if (const Arg *A =
112
3
          Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
113
2
    CmdArgs.push_back(Args.MakeArgString(
114
2
        Twine(PluginOptPrefix) + "opt-remarks-passes=" + A->getValue()));
115
116
3
  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
117
3
                                       "opt-remarks-format=" + Format.data()));
118
3
}
119
120
static void renderRemarksHotnessOptions(const ArgList &Args,
121
                                        ArgStringList &CmdArgs,
122
424
                                        const StringRef PluginOptPrefix) {
123
424
  if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
124
424
                   options::OPT_fno_diagnostics_show_hotness, false))
125
0
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
126
0
                                         "opt-remarks-with-hotness"));
127
128
424
  if (const Arg *A =
129
424
          Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
130
5
    CmdArgs.push_back(
131
5
        Args.MakeArgString(Twine(PluginOptPrefix) +
132
5
                           "opt-remarks-hotness-threshold=" + A->getValue()));
133
424
}
134
135
static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg,
136
                                                 llvm::Triple T,
137
269
                                                 StringRef Processor) {
138
  // Warn no-cumode for AMDGCN processors not supporing WGP mode.
139
269
  if (!T.isAMDGPU())
140
223
    return false;
141
46
  auto GPUKind = T.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Processor)
142
46
                              : 
llvm::AMDGPU::parseArchR600(Processor)0
;
143
46
  auto GPUFeatures = T.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(GPUKind)
144
46
                                  : 
llvm::AMDGPU::getArchAttrR600(GPUKind)0
;
145
46
  if (GPUFeatures & llvm::AMDGPU::FEATURE_WGP)
146
28
    return false;
147
18
  return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode);
148
46
}
149
150
void tools::addPathIfExists(const Driver &D, const Twine &Path,
151
35.6k
                            ToolChain::path_list &Paths) {
152
35.6k
  if (D.getVFS().exists(Path))
153
6.84k
    Paths.push_back(Path.str());
154
35.6k
}
155
156
void tools::handleTargetFeaturesGroup(const Driver &D,
157
                                      const llvm::Triple &Triple,
158
                                      const ArgList &Args,
159
                                      std::vector<StringRef> &Features,
160
2.62k
                                      OptSpecifier Group) {
161
2.62k
  std::set<StringRef> Warned;
162
2.62k
  for (const Arg *A : Args.filtered(Group)) {
163
269
    StringRef Name = A->getOption().getName();
164
269
    A->claim();
165
166
    // Skip over "-m".
167
269
    assert(Name.startswith("m") && "Invalid feature name.");
168
269
    Name = Name.substr(1);
169
170
269
    auto Proc = getCPUName(D, Args, Triple);
171
269
    if (shouldIgnoreUnsupportedTargetFeature(*A, Triple, Proc)) {
172
9
      if (Warned.count(Name) == 0) {
173
4
        D.getDiags().Report(
174
4
            clang::diag::warn_drv_unsupported_option_for_processor)
175
4
            << A->getAsString(Args) << Proc;
176
4
        Warned.insert(Name);
177
4
      }
178
9
      continue;
179
9
    }
180
181
260
    bool IsNegative = Name.startswith("no-");
182
260
    if (IsNegative)
183
86
      Name = Name.substr(3);
184
185
260
    Features.push_back(Args.MakeArgString((IsNegative ? 
"-"86
:
"+"174
) + Name));
186
260
  }
187
2.62k
}
188
189
SmallVector<StringRef>
190
49.2k
tools::unifyTargetFeatures(ArrayRef<StringRef> Features) {
191
  // Only add a feature if it hasn't been seen before starting from the end.
192
49.2k
  SmallVector<StringRef> UnifiedFeatures;
193
49.2k
  llvm::DenseSet<StringRef> UsedFeatures;
194
188k
  for (StringRef Feature : llvm::reverse(Features)) {
195
188k
    if (UsedFeatures.insert(Feature.drop_front()).second)
196
162k
      UnifiedFeatures.insert(UnifiedFeatures.begin(), Feature);
197
188k
  }
198
199
49.2k
  return UnifiedFeatures;
200
49.2k
}
201
202
void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
203
243k
                             const char *ArgName, const char *EnvVar) {
204
243k
  const char *DirList = ::getenv(EnvVar);
205
243k
  bool CombinedArg = false;
206
207
243k
  if (!DirList)
208
243k
    return; // Nothing to do.
209
210
48
  StringRef Name(ArgName);
211
48
  if (Name.equals("-I") || 
Name.equals("-L")33
||
Name.empty()11
)
212
44
    CombinedArg = true;
213
214
48
  StringRef Dirs(DirList);
215
48
  if (Dirs.empty()) // Empty string should not add '.'.
216
0
    return;
217
218
48
  StringRef::size_type Delim;
219
51
  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
220
3
    if (Delim == 0) { // Leading colon.
221
0
      if (CombinedArg) {
222
0
        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
223
0
      } else {
224
0
        CmdArgs.push_back(ArgName);
225
0
        CmdArgs.push_back(".");
226
0
      }
227
3
    } else {
228
3
      if (CombinedArg) {
229
1
        CmdArgs.push_back(
230
1
            Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
231
2
      } else {
232
2
        CmdArgs.push_back(ArgName);
233
2
        CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
234
2
      }
235
3
    }
236
3
    Dirs = Dirs.substr(Delim + 1);
237
3
  }
238
239
48
  if (Dirs.empty()) { // Trailing colon.
240
0
    if (CombinedArg) {
241
0
      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
242
0
    } else {
243
0
      CmdArgs.push_back(ArgName);
244
0
      CmdArgs.push_back(".");
245
0
    }
246
48
  } else { // Add the last path.
247
48
    if (CombinedArg) {
248
44
      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
249
44
    } else {
250
4
      CmdArgs.push_back(ArgName);
251
4
      CmdArgs.push_back(Args.MakeArgString(Dirs));
252
4
    }
253
48
  }
254
48
}
255
256
void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
257
                            const ArgList &Args, ArgStringList &CmdArgs,
258
6.39k
                            const JobAction &JA) {
259
6.39k
  const Driver &D = TC.getDriver();
260
261
  // Add extra linker input arguments which are not treated as inputs
262
  // (constructed via -Xarch_).
263
6.39k
  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
264
265
  // LIBRARY_PATH are included before user inputs and only supported on native
266
  // toolchains.
267
6.39k
  if (!TC.isCrossCompiling())
268
4.43k
    addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
269
270
12.6k
  for (const auto &II : Inputs) {
271
    // If the current tool chain refers to an OpenMP offloading host, we
272
    // should ignore inputs that refer to OpenMP offloading devices -
273
    // they will be embedded according to a proper linker script.
274
12.6k
    if (auto *IA = II.getAction())
275
12.6k
      if ((JA.isHostOffloading(Action::OFK_OpenMP) &&
276
12.6k
           
IA->isDeviceOffloading(Action::OFK_OpenMP)7
))
277
0
        continue;
278
279
12.6k
    if (!TC.HasNativeLLVMSupport() && 
types::isLLVMIR(II.getType())438
)
280
      // Don't try to pass LLVM inputs unless we have native support.
281
1
      D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
282
283
    // Add filenames immediately.
284
12.6k
    if (II.isFilename()) {
285
6.77k
      CmdArgs.push_back(II.getFilename());
286
6.77k
      continue;
287
6.77k
    }
288
289
    // In some error cases, the input could be Nothing; skip those.
290
5.87k
    if (II.isNothing())
291
2
      continue;
292
293
    // Otherwise, this is a linker input argument.
294
5.86k
    const Arg &A = II.getInputArg();
295
296
    // Handle reserved library options.
297
5.86k
    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
298
3
      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
299
5.86k
    else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
300
2
      TC.AddCCKextLibArgs(Args, CmdArgs);
301
5.86k
    else
302
5.86k
      A.renderAsInput(Args, CmdArgs);
303
5.86k
  }
304
6.39k
}
305
306
void tools::addLinkerCompressDebugSectionsOption(
307
    const ToolChain &TC, const llvm::opt::ArgList &Args,
308
2.09k
    llvm::opt::ArgStringList &CmdArgs) {
309
  // GNU ld supports --compress-debug-sections=none|zlib|zlib-gnu|zlib-gabi
310
  // whereas zlib is an alias to zlib-gabi and zlib-gnu is obsoleted. Therefore
311
  // -gz=none|zlib are translated to --compress-debug-sections=none|zlib. -gz
312
  // is not translated since ld --compress-debug-sections option requires an
313
  // argument.
314
2.09k
  if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) {
315
14
    StringRef V = A->getValue();
316
14
    if (V == "none" || 
V == "zlib"10
||
V == "zstd"0
)
317
14
      CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V));
318
0
    else
319
0
      TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
320
0
          << A->getSpelling() << V;
321
14
  }
322
2.09k
}
323
324
void tools::AddTargetFeature(const ArgList &Args,
325
                             std::vector<StringRef> &Features,
326
                             OptSpecifier OnOpt, OptSpecifier OffOpt,
327
5.39k
                             StringRef FeatureName) {
328
5.39k
  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
329
102
    if (A->getOption().matches(OnOpt))
330
63
      Features.push_back(Args.MakeArgString("+" + FeatureName));
331
39
    else
332
39
      Features.push_back(Args.MakeArgString("-" + FeatureName));
333
102
  }
334
5.39k
}
335
336
/// Get the (LLVM) name of the AMDGPU gpu we are targeting.
337
static std::string getAMDGPUTargetGPU(const llvm::Triple &T,
338
1.09k
                                      const ArgList &Args) {
339
1.09k
  Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
340
1.09k
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
341
1.05k
    auto GPUName = getProcessorFromTargetID(T, A->getValue());
342
1.05k
    return llvm::StringSwitch<std::string>(GPUName)
343
1.05k
        .Cases("rv630", "rv635", "r600")
344
1.05k
        .Cases("rv610", "rv620", "rs780", "rs880")
345
1.05k
        .Case("rv740", "rv770")
346
1.05k
        .Case("palm", "cedar")
347
1.05k
        .Cases("sumo", "sumo2", "sumo")
348
1.05k
        .Case("hemlock", "cypress")
349
1.05k
        .Case("aruba", "cayman")
350
1.05k
        .Default(GPUName.str());
351
1.05k
  }
352
40
  if (MArch)
353
11
    return getProcessorFromTargetID(T, MArch->getValue()).str();
354
29
  return "";
355
40
}
356
357
3
static std::string getLanaiTargetCPU(const ArgList &Args) {
358
3
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
359
0
    return A->getValue();
360
0
  }
361
3
  return "";
362
3
}
363
364
/// Get the (LLVM) name of the WebAssembly cpu we are targeting.
365
175
static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
366
  // If we have -mcpu=, use that.
367
175
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
368
10
    StringRef CPU = A->getValue();
369
370
#ifdef __wasm__
371
    // Handle "native" by examining the host. "native" isn't meaningful when
372
    // cross compiling, so only support this when the host is also WebAssembly.
373
    if (CPU == "native")
374
      return llvm::sys::getHostCPUName();
375
#endif
376
377
10
    return CPU;
378
10
  }
379
380
165
  return "generic";
381
175
}
382
383
std::string tools::getCPUName(const Driver &D, const ArgList &Args,
384
52.1k
                              const llvm::Triple &T, bool FromAs) {
385
52.1k
  Arg *A;
386
387
52.1k
  switch (T.getArch()) {
388
214
  default:
389
214
    return "";
390
391
1.68k
  case llvm::Triple::aarch64:
392
1.69k
  case llvm::Triple::aarch64_32:
393
1.92k
  case llvm::Triple::aarch64_be:
394
1.92k
    return aarch64::getAArch64TargetCPU(Args, T, A);
395
396
2.32k
  case llvm::Triple::arm:
397
2.72k
  case llvm::Triple::armeb:
398
4.08k
  case llvm::Triple::thumb:
399
4.29k
  case llvm::Triple::thumbeb: {
400
4.29k
    StringRef MArch, MCPU;
401
4.29k
    arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
402
4.29k
    return arm::getARMTargetCPU(MCPU, MArch, T);
403
4.08k
  }
404
405
259
  case llvm::Triple::avr:
406
259
    if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ))
407
221
      return A->getValue();
408
38
    return "";
409
410
47
  case llvm::Triple::m68k:
411
47
    return m68k::getM68kTargetCPU(Args);
412
413
284
  case llvm::Triple::mips:
414
345
  case llvm::Triple::mipsel:
415
436
  case llvm::Triple::mips64:
416
503
  case llvm::Triple::mips64el: {
417
503
    StringRef CPUName;
418
503
    StringRef ABIName;
419
503
    mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
420
503
    return std::string(CPUName);
421
436
  }
422
423
5
  case llvm::Triple::nvptx:
424
63
  case llvm::Triple::nvptx64:
425
63
    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
426
63
      return A->getValue();
427
0
    return "";
428
429
295
  case llvm::Triple::ppc:
430
304
  case llvm::Triple::ppcle:
431
611
  case llvm::Triple::ppc64:
432
795
  case llvm::Triple::ppc64le:
433
795
    return ppc::getPPCTargetCPU(D, Args, T);
434
435
36
  case llvm::Triple::csky:
436
36
    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
437
9
      return A->getValue();
438
27
    else if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
439
14
      return A->getValue();
440
13
    else
441
13
      return "ck810";
442
404
  case llvm::Triple::riscv32:
443
764
  case llvm::Triple::riscv64:
444
764
    return riscv::getRISCVTargetCPU(Args, T);
445
446
3
  case llvm::Triple::bpfel:
447
6
  case llvm::Triple::bpfeb:
448
6
    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
449
0
      return A->getValue();
450
6
    return "";
451
452
175
  case llvm::Triple::sparc:
453
182
  case llvm::Triple::sparcel:
454
275
  case llvm::Triple::sparcv9:
455
275
    return sparc::getSparcTargetCPU(D, Args, T);
456
457
11.2k
  case llvm::Triple::x86:
458
41.2k
  case llvm::Triple::x86_64:
459
41.2k
    return x86::getX86TargetCPU(D, Args, T);
460
461
159
  case llvm::Triple::hexagon:
462
159
    return "hexagon" +
463
159
           toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
464
465
3
  case llvm::Triple::lanai:
466
3
    return getLanaiTargetCPU(Args);
467
468
100
  case llvm::Triple::systemz:
469
100
    return systemz::getSystemZTargetCPU(Args);
470
471
54
  case llvm::Triple::r600:
472
1.09k
  case llvm::Triple::amdgcn:
473
1.09k
    return getAMDGPUTargetGPU(T, Args);
474
475
129
  case llvm::Triple::wasm32:
476
175
  case llvm::Triple::wasm64:
477
175
    return std::string(getWebAssemblyTargetCPU(Args));
478
479
36
  case llvm::Triple::loongarch32:
480
154
  case llvm::Triple::loongarch64:
481
154
    return loongarch::getLoongArchTargetCPU(Args, T);
482
52.1k
  }
483
52.1k
}
484
485
static void getWebAssemblyTargetFeatures(const Driver &D,
486
                                         const llvm::Triple &Triple,
487
                                         const ArgList &Args,
488
129
                                         std::vector<StringRef> &Features) {
489
129
  handleTargetFeaturesGroup(D, Triple, Args, Features,
490
129
                            options::OPT_m_wasm_Features_Group);
491
129
}
492
493
void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
494
                              const ArgList &Args, ArgStringList &CmdArgs,
495
48.9k
                              bool ForAS, bool IsAux) {
496
48.9k
  std::vector<StringRef> Features;
497
48.9k
  switch (Triple.getArch()) {
498
302
  default:
499
302
    break;
500
302
  case llvm::Triple::mips:
501
314
  case llvm::Triple::mipsel:
502
389
  case llvm::Triple::mips64:
503
437
  case llvm::Triple::mips64el:
504
437
    mips::getMIPSTargetFeatures(D, Triple, Args, Features);
505
437
    break;
506
1.20k
  case llvm::Triple::arm:
507
1.40k
  case llvm::Triple::armeb:
508
2.09k
  case llvm::Triple::thumb:
509
2.19k
  case llvm::Triple::thumbeb:
510
2.19k
    arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS);
511
2.19k
    break;
512
234
  case llvm::Triple::ppc:
513
242
  case llvm::Triple::ppcle:
514
480
  case llvm::Triple::ppc64:
515
597
  case llvm::Triple::ppc64le:
516
597
    ppc::getPPCTargetFeatures(D, Triple, Args, Features);
517
597
    break;
518
402
  case llvm::Triple::riscv32:
519
758
  case llvm::Triple::riscv64:
520
758
    riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
521
758
    break;
522
100
  case llvm::Triple::systemz:
523
100
    systemz::getSystemZTargetFeatures(D, Args, Features);
524
100
    break;
525
1.59k
  case llvm::Triple::aarch64:
526
1.60k
  case llvm::Triple::aarch64_32:
527
1.83k
  case llvm::Triple::aarch64_be:
528
1.83k
    aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS);
529
1.83k
    break;
530
11.2k
  case llvm::Triple::x86:
531
41.1k
  case llvm::Triple::x86_64:
532
41.1k
    x86::getX86TargetFeatures(D, Triple, Args, Features);
533
41.1k
    break;
534
137
  case llvm::Triple::hexagon:
535
137
    hexagon::getHexagonTargetFeatures(D, Triple, Args, Features);
536
137
    break;
537
97
  case llvm::Triple::wasm32:
538
129
  case llvm::Triple::wasm64:
539
129
    getWebAssemblyTargetFeatures(D, Triple, Args, Features);
540
129
    break;
541
133
  case llvm::Triple::sparc:
542
139
  case llvm::Triple::sparcel:
543
209
  case llvm::Triple::sparcv9:
544
209
    sparc::getSparcTargetFeatures(D, Args, Features);
545
209
    break;
546
54
  case llvm::Triple::r600:
547
764
  case llvm::Triple::amdgcn:
548
764
    amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features);
549
764
    break;
550
5
  case llvm::Triple::nvptx:
551
63
  case llvm::Triple::nvptx64:
552
63
    NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features);
553
63
    break;
554
47
  case llvm::Triple::m68k:
555
47
    m68k::getM68kTargetFeatures(D, Triple, Args, Features);
556
47
    break;
557
49
  case llvm::Triple::msp430:
558
49
    msp430::getMSP430TargetFeatures(D, Args, Features);
559
49
    break;
560
4
  case llvm::Triple::ve:
561
4
    ve::getVETargetFeatures(D, Args, Features);
562
4
    break;
563
36
  case llvm::Triple::csky:
564
36
    csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features);
565
36
    break;
566
36
  case llvm::Triple::loongarch32:
567
154
  case llvm::Triple::loongarch64:
568
154
    loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features);
569
154
    break;
570
48.9k
  }
571
572
162k
  
for (auto Feature : unifyTargetFeatures(Features))48.9k
{
573
162k
    CmdArgs.push_back(IsAux ? 
"-aux-target-feature"50
:
"-target-feature"162k
);
574
162k
    CmdArgs.push_back(Feature.data());
575
162k
  }
576
48.9k
}
577
578
3.80k
llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
579
3.80k
  Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
580
3.80k
  if (!LtoJobsArg)
581
3.80k
    return {};
582
6
  if (!llvm::get_threadpool_strategy(LtoJobsArg->getValue()))
583
0
    D.Diag(diag::err_drv_invalid_int_value)
584
0
        << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue();
585
6
  return LtoJobsArg->getValue();
586
3.80k
}
587
588
// PS4/PS5 uses -ffunction-sections and -fdata-sections by default.
589
48.3k
bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
590
48.3k
  return Triple.isPS();
591
48.3k
}
592
593
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
594
                          ArgStringList &CmdArgs, const InputInfo &Output,
595
424
                          const InputInfo &Input, bool IsThinLTO) {
596
424
  const bool IsOSAIX = ToolChain.getTriple().isOSAIX();
597
424
  const bool IsAMDGCN = ToolChain.getTriple().isAMDGCN();
598
424
  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
599
424
  const Driver &D = ToolChain.getDriver();
600
424
  if (llvm::sys::path::filename(Linker) != "ld.lld" &&
601
424
      
llvm::sys::path::stem(Linker) != "ld.lld"105
) {
602
    // Tell the linker to load the plugin. This has to come before
603
    // AddLinkerInputs as gold requires -plugin and AIX ld requires -bplugin to
604
    // come before any -plugin-opt/-bplugin_opt that -Wl might forward.
605
105
    const char *PluginPrefix = IsOSAIX ? 
"-bplugin:"31
:
""74
;
606
105
    const char *PluginName = IsOSAIX ? 
"/libLTO"31
:
"/LLVMgold"74
;
607
608
105
    if (!IsOSAIX)
609
74
      CmdArgs.push_back("-plugin");
610
611
#if defined(_WIN32)
612
    const char *Suffix = ".dll";
613
#elif defined(__APPLE__)
614
    const char *Suffix = ".dylib";
615
#else
616
    const char *Suffix = ".so";
617
#endif
618
619
105
    SmallString<1024> Plugin;
620
105
    llvm::sys::path::native(Twine(D.Dir) +
621
105
                                "/../" CLANG_INSTALL_LIBDIR_BASENAME +
622
105
                                PluginName + Suffix,
623
105
                            Plugin);
624
105
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginPrefix) + Plugin));
625
319
  } else {
626
    // Tell LLD to find and use .llvm.lto section in regular relocatable object
627
    // files
628
319
    if (Args.hasArg(options::OPT_ffat_lto_objects))
629
1
      CmdArgs.push_back("--fat-lto-objects");
630
319
  }
631
632
424
  const char *PluginOptPrefix = IsOSAIX ? 
"-bplugin_opt:"31
:
"-plugin-opt="393
;
633
424
  const char *ExtraDash = IsOSAIX ? 
"-"31
:
""393
;
634
635
  // Note, this solution is far from perfect, better to encode it into IR
636
  // metadata, but this may not be worth it, since it looks like aranges is on
637
  // the way out.
638
424
  if (Args.hasArg(options::OPT_gdwarf_aranges)) {
639
0
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
640
0
                                         "-generate-arange-section"));
641
0
  }
642
643
  // Try to pass driver level flags relevant to LTO code generation down to
644
  // the plugin.
645
646
  // Handle flags for selecting CPU variants.
647
424
  std::string CPU = getCPUName(D, Args, ToolChain.getTriple());
648
424
  if (!CPU.empty())
649
423
    CmdArgs.push_back(
650
423
        Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + CPU));
651
652
424
  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
653
    // The optimization level matches
654
    // CompilerInvocation.cpp:getOptimizationLevel().
655
28
    StringRef OOpt;
656
28
    if (A->getOption().matches(options::OPT_O4) ||
657
28
        A->getOption().matches(options::OPT_Ofast))
658
2
      OOpt = "3";
659
26
    else if (A->getOption().matches(options::OPT_O)) {
660
24
      OOpt = A->getValue();
661
24
      if (OOpt == "g")
662
3
        OOpt = "1";
663
21
      else if (OOpt == "s" || 
OOpt == "z"18
)
664
6
        OOpt = "2";
665
24
    } else 
if (2
A->getOption().matches(options::OPT_O0)2
)
666
2
      OOpt = "0";
667
28
    if (!OOpt.empty()) {
668
28
      CmdArgs.push_back(
669
28
          Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "O" + OOpt));
670
28
      if (IsAMDGCN)
671
8
        CmdArgs.push_back(Args.MakeArgString(Twine("--lto-CGO") + OOpt));
672
28
    }
673
28
  }
674
675
424
  if (Args.hasArg(options::OPT_gsplit_dwarf))
676
7
    CmdArgs.push_back(Args.MakeArgString(
677
7
        Twine(PluginOptPrefix) + "dwo_dir=" + Output.getFilename() + "_dwo"));
678
679
424
  if (IsThinLTO && 
!IsOSAIX28
)
680
27
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + "thinlto"));
681
397
  else if (IsThinLTO && 
IsOSAIX1
)
682
1
    CmdArgs.push_back(Args.MakeArgString(Twine("-bdbg:thinlto")));
683
684
  // Matrix intrinsic lowering happens at link time with ThinLTO. Enable
685
  // LowerMatrixIntrinsicsPass, which is transitively called by
686
  // buildThinLTODefaultPipeline under EnableMatrix.
687
424
  if (IsThinLTO && 
Args.hasArg(options::OPT_fenable_matrix)28
)
688
2
    CmdArgs.push_back(
689
2
        Args.MakeArgString(Twine(PluginOptPrefix) + "-enable-matrix"));
690
691
424
  StringRef Parallelism = getLTOParallelism(Args, D);
692
424
  if (!Parallelism.empty())
693
3
    CmdArgs.push_back(
694
3
        Args.MakeArgString(Twine(PluginOptPrefix) + "jobs=" + Parallelism));
695
696
  // If an explicit debugger tuning argument appeared, pass it along.
697
424
  if (Arg *A =
698
424
          Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
699
14
    if (A->getOption().matches(options::OPT_glldb))
700
1
      CmdArgs.push_back(
701
1
          Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=lldb"));
702
13
    else if (A->getOption().matches(options::OPT_gsce))
703
0
      CmdArgs.push_back(
704
0
          Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=sce"));
705
13
    else if (A->getOption().matches(options::OPT_gdbx))
706
2
      CmdArgs.push_back(
707
2
          Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=dbx"));
708
11
    else
709
11
      CmdArgs.push_back(
710
11
          Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=gdb"));
711
14
  }
712
713
424
  if (IsOSAIX) {
714
31
    if (!ToolChain.useIntegratedAs())
715
1
      CmdArgs.push_back(
716
1
          Args.MakeArgString(Twine(PluginOptPrefix) + "-no-integrated-as=1"));
717
718
    // On AIX, clang assumes strict-dwarf is true if any debug option is
719
    // specified, unless it is told explicitly not to assume so.
720
31
    Arg *A = Args.getLastArg(options::OPT_g_Group);
721
31
    bool EnableDebugInfo = A && 
!A->getOption().matches(options::OPT_g0)10
&&
722
31
                           
!A->getOption().matches(options::OPT_ggdb0)9
;
723
31
    if (EnableDebugInfo && Args.hasFlag(options::OPT_gstrict_dwarf,
724
8
                                        options::OPT_gno_strict_dwarf, true))
725
7
      CmdArgs.push_back(
726
7
          Args.MakeArgString(Twine(PluginOptPrefix) + "-strict-dwarf=true"));
727
728
31
    for (const Arg *A : Args.filtered_reverse(options::OPT_mabi_EQ)) {
729
1
      StringRef V = A->getValue();
730
1
      if (V == "vec-default")
731
0
        break;
732
1
      if (V == "vec-extabi") {
733
1
        CmdArgs.push_back(
734
1
            Args.MakeArgString(Twine(PluginOptPrefix) + "-vec-extabi"));
735
1
        break;
736
1
      }
737
1
    }
738
31
  }
739
740
424
  bool UseSeparateSections =
741
424
      isUseSeparateSections(ToolChain.getEffectiveTriple());
742
743
424
  if (Args.hasFlag(options::OPT_ffunction_sections,
744
424
                   options::OPT_fno_function_sections, UseSeparateSections))
745
1
    CmdArgs.push_back(
746
1
        Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=1"));
747
423
  else if (Args.hasArg(options::OPT_fno_function_sections))
748
1
    CmdArgs.push_back(
749
1
        Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=0"));
750
751
424
  bool DataSectionsTurnedOff = false;
752
424
  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
753
424
                   UseSeparateSections)) {
754
1
    CmdArgs.push_back(
755
1
        Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=1"));
756
423
  } else if (Args.hasArg(options::OPT_fno_data_sections)) {
757
3
    DataSectionsTurnedOff = true;
758
3
    CmdArgs.push_back(
759
3
        Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=0"));
760
3
  }
761
762
424
  if (Args.hasArg(options::OPT_mxcoff_roptr) ||
763
424
      
Args.hasArg(options::OPT_mno_xcoff_roptr)421
) {
764
5
    bool HasRoptr = Args.hasFlag(options::OPT_mxcoff_roptr,
765
5
                                 options::OPT_mno_xcoff_roptr, false);
766
5
    StringRef OptStr = HasRoptr ? 
"-mxcoff-roptr"3
:
"-mno-xcoff-roptr"2
;
767
768
5
    if (!IsOSAIX)
769
2
      D.Diag(diag::err_drv_unsupported_opt_for_target)
770
2
          << OptStr << ToolChain.getTriple().str();
771
772
5
    if (HasRoptr) {
773
      // The data sections option is on by default on AIX. We only need to error
774
      // out when -fno-data-sections is specified explicitly to turn off data
775
      // sections.
776
3
      if (DataSectionsTurnedOff)
777
1
        D.Diag(diag::err_roptr_requires_data_sections);
778
779
3
      CmdArgs.push_back(
780
3
          Args.MakeArgString(Twine(PluginOptPrefix) + "-mxcoff-roptr"));
781
3
    }
782
5
  }
783
784
  // Pass an option to enable split machine functions.
785
424
  if (auto *A = Args.getLastArg(options::OPT_fsplit_machine_functions,
786
424
                                options::OPT_fno_split_machine_functions)) {
787
2
    if (A->getOption().matches(options::OPT_fsplit_machine_functions))
788
1
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
789
1
                                           "-split-machine-functions"));
790
2
  }
791
792
424
  if (Arg *A = getLastProfileSampleUseArg(Args)) {
793
1
    StringRef FName = A->getValue();
794
1
    if (!llvm::sys::fs::exists(FName))
795
0
      D.Diag(diag::err_drv_no_such_file) << FName;
796
1
    else
797
1
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
798
1
                                           "sample-profile=" + FName));
799
1
  }
800
801
424
  if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {
802
1
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
803
1
                                         "cs-profile-generate"));
804
1
    if (CSPGOGenerateArg->getOption().matches(
805
1
            options::OPT_fcs_profile_generate_EQ)) {
806
0
      SmallString<128> Path(CSPGOGenerateArg->getValue());
807
0
      llvm::sys::path::append(Path, "default_%m.profraw");
808
0
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
809
0
                                           "cs-profile-path=" + Path));
810
0
    } else
811
1
      CmdArgs.push_back(
812
1
          Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
813
1
                             "cs-profile-path=default_%m.profraw"));
814
423
  } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {
815
1
    SmallString<128> Path(
816
1
        ProfileUseArg->getNumValues() == 0 ? "" : 
ProfileUseArg->getValue()0
);
817
1
    if (Path.empty() || 
llvm::sys::fs::is_directory(Path)0
)
818
1
      llvm::sys::path::append(Path, "default.profdata");
819
1
    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
820
1
                                         "cs-profile-path=" + Path));
821
1
  }
822
823
  // This controls whether or not we perform JustMyCode instrumentation.
824
424
  if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
825
1
    if (ToolChain.getEffectiveTriple().isOSBinFormatELF())
826
1
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
827
1
                                           "-enable-jmc-instrument"));
828
0
    else
829
0
      D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
830
1
  }
831
832
424
  if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
833
424
                   ToolChain.getTriple().hasDefaultEmulatedTLS())) {
834
5
    CmdArgs.push_back(
835
5
        Args.MakeArgString(Twine(PluginOptPrefix) + "-emulated-tls"));
836
5
  }
837
838
424
  if (Args.hasFlag(options::OPT_fstack_size_section,
839
424
                   options::OPT_fno_stack_size_section, false))
840
1
    CmdArgs.push_back(
841
1
        Args.MakeArgString(Twine(PluginOptPrefix) + "-stack-size-section"));
842
843
  // Setup statistics file output.
844
424
  SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
845
424
  if (!StatsFile.empty())
846
2
    CmdArgs.push_back(
847
2
        Args.MakeArgString(Twine(PluginOptPrefix) + "stats-file=" + StatsFile));
848
849
  // Setup crash diagnostics dir.
850
424
  if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))
851
1
    CmdArgs.push_back(Args.MakeArgString(
852
1
        Twine(PluginOptPrefix) + "-crash-diagnostics-dir=" + A->getValue()));
853
854
424
  addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true, PluginOptPrefix);
855
856
  // Handle remark diagnostics on screen options: '-Rpass-*'.
857
424
  renderRpassOptions(Args, CmdArgs, PluginOptPrefix);
858
859
  // Handle serialized remarks options: '-fsave-optimization-record'
860
  // and '-foptimization-record-*'.
861
424
  if (willEmitRemarks(Args))
862
3
    renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
863
3
                         Output, PluginOptPrefix);
864
865
  // Handle remarks hotness/threshold related options.
866
424
  renderRemarksHotnessOptions(Args, CmdArgs, PluginOptPrefix);
867
868
424
  addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(),
869
424
                         /*IsLTO=*/true, PluginOptPrefix);
870
424
}
871
872
/// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the
873
/// LLVM C library for GPUs.
874
static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
875
7
                                ArgStringList &CmdArgs) {
876
7
  if (Args.hasArg(options::OPT_nogpulib) || 
Args.hasArg(options::OPT_nolibc)1
)
877
6
    return;
878
879
  // Check the resource directory for the LLVM libc GPU declarations. If it's
880
  // found we can assume that LLVM was built with support for the GPU libc.
881
1
  SmallString<256> LibCDecls(TC.getDriver().ResourceDir);
882
1
  llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers",
883
1
                          "llvm-libc-decls");
884
1
  bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
885
1
                 
llvm::sys::fs::is_directory(LibCDecls)0
;
886
1
  if (Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) {
887
0
    CmdArgs.push_back("-lcgpu");
888
0
    CmdArgs.push_back("-lmgpu");
889
0
  }
890
1
}
891
892
void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
893
                                        const ArgList &Args,
894
61
                                        ArgStringList &CmdArgs) {
895
  // Default to clang lib / lib64 folder, i.e. the same location as device
896
  // runtime.
897
61
  SmallString<256> DefaultLibPath =
898
61
      llvm::sys::path::parent_path(TC.getDriver().Dir);
899
61
  llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
900
61
  CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
901
61
}
902
903
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
904
107
                                 ArgStringList &CmdArgs) {
905
107
  if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
906
107
                    options::OPT_fno_rtlib_add_rpath, false))
907
102
    return;
908
909
10
  
for (const auto &CandidateRPath : TC.getArchSpecificLibPaths())5
{
910
10
    if (TC.getVFS().exists(CandidateRPath)) {
911
5
      CmdArgs.push_back("-rpath");
912
5
      CmdArgs.push_back(Args.MakeArgString(CandidateRPath));
913
5
    }
914
10
  }
915
5
}
916
917
bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
918
                             const ArgList &Args, bool ForceStaticHostRuntime,
919
5.19k
                             bool IsOffloadingHost, bool GompNeedsRT) {
920
5.19k
  if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
921
5.19k
                    options::OPT_fno_openmp, false))
922
5.13k
    return false;
923
924
63
  Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args);
925
926
63
  if (RTKind == Driver::OMPRT_Unknown)
927
    // Already diagnosed.
928
2
    return false;
929
930
61
  if (ForceStaticHostRuntime)
931
12
    CmdArgs.push_back("-Bstatic");
932
933
61
  switch (RTKind) {
934
35
  case Driver::OMPRT_OMP:
935
35
    CmdArgs.push_back("-lomp");
936
35
    break;
937
13
  case Driver::OMPRT_GOMP:
938
13
    CmdArgs.push_back("-lgomp");
939
13
    break;
940
13
  case Driver::OMPRT_IOMP5:
941
13
    CmdArgs.push_back("-liomp5");
942
13
    break;
943
0
  case Driver::OMPRT_Unknown:
944
0
    break;
945
61
  }
946
947
61
  if (ForceStaticHostRuntime)
948
12
    CmdArgs.push_back("-Bdynamic");
949
950
61
  if (RTKind == Driver::OMPRT_GOMP && 
GompNeedsRT13
)
951
6
      CmdArgs.push_back("-lrt");
952
953
61
  if (IsOffloadingHost)
954
7
    CmdArgs.push_back("-lomptarget");
955
956
61
  if (IsOffloadingHost && 
!Args.hasArg(options::OPT_nogpulib)7
)
957
1
    CmdArgs.push_back("-lomptarget.devicertl");
958
959
61
  if (IsOffloadingHost)
960
7
    addOpenMPDeviceLibC(TC, Args, CmdArgs);
961
962
61
  addArchSpecificRPath(TC, Args, CmdArgs);
963
61
  addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs);
964
965
61
  return true;
966
61
}
967
968
void tools::addFortranRuntimeLibs(const ToolChain &TC,
969
4
                                  llvm::opt::ArgStringList &CmdArgs) {
970
4
  if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
971
0
    CmdArgs.push_back("Fortran_main.lib");
972
0
    CmdArgs.push_back("FortranRuntime.lib");
973
0
    CmdArgs.push_back("FortranDecimal.lib");
974
4
  } else {
975
4
    CmdArgs.push_back("-lFortran_main");
976
4
    CmdArgs.push_back("-lFortranRuntime");
977
4
    CmdArgs.push_back("-lFortranDecimal");
978
4
  }
979
4
}
980
981
void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
982
                                         const llvm::opt::ArgList &Args,
983
4
                                         ArgStringList &CmdArgs) {
984
  // Default to the <driver-path>/../lib directory. This works fine on the
985
  // platforms that we have tested so far. We will probably have to re-fine
986
  // this in the future. In particular, on some platforms, we may need to use
987
  // lib64 instead of lib.
988
4
  SmallString<256> DefaultLibPath =
989
4
      llvm::sys::path::parent_path(TC.getDriver().Dir);
990
4
  llvm::sys::path::append(DefaultLibPath, "lib");
991
4
  if (TC.getTriple().isKnownWindowsMSVCEnvironment())
992
0
    CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
993
4
  else
994
4
    CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
995
4
}
996
997
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
998
                                ArgStringList &CmdArgs, StringRef Sanitizer,
999
539
                                bool IsShared, bool IsWhole) {
1000
  // Wrap any static runtimes that must be forced into executable in
1001
  // whole-archive.
1002
539
  if (IsWhole) 
CmdArgs.push_back("--whole-archive")480
;
1003
539
  CmdArgs.push_back(TC.getCompilerRTArgString(
1004
539
      Args, Sanitizer, IsShared ? 
ToolChain::FT_Shared46
:
ToolChain::FT_Static493
));
1005
539
  if (IsWhole) 
CmdArgs.push_back("--no-whole-archive")480
;
1006
1007
539
  if (IsShared) {
1008
46
    addArchSpecificRPath(TC, Args, CmdArgs);
1009
46
  }
1010
539
}
1011
1012
// Tries to use a file with the list of dynamic symbols that need to be exported
1013
// from the runtime library. Returns true if the file was found.
1014
static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
1015
                                    ArgStringList &CmdArgs,
1016
345
                                    StringRef Sanitizer) {
1017
345
  bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
1018
1019
  // Solaris ld defaults to --export-dynamic behaviour but doesn't support
1020
  // the option, so don't try to pass it.
1021
345
  if (TC.getTriple().isOSSolaris() && 
!LinkerIsGnuLd8
)
1022
7
    return true;
1023
338
  SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
1024
338
  if (llvm::sys::fs::exists(SanRT + ".syms")) {
1025
21
    CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
1026
21
    return true;
1027
21
  }
1028
317
  return false;
1029
338
}
1030
1031
void tools::addAsNeededOption(const ToolChain &TC,
1032
                              const llvm::opt::ArgList &Args,
1033
                              llvm::opt::ArgStringList &CmdArgs,
1034
5.78k
                              bool as_needed) {
1035
5.78k
  assert(!TC.getTriple().isOSAIX() &&
1036
5.78k
         "AIX linker does not support any form of --as-needed option yet.");
1037
5.78k
  bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
1038
1039
  // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases
1040
  // for the native forms -z ignore/-z record, they are missing in Illumos,
1041
  // so always use the native form.
1042
  // GNU ld doesn't support -z ignore/-z record, so don't use them even on
1043
  // Solaris.
1044
5.78k
  if (TC.getTriple().isOSSolaris() && 
!LinkerIsGnuLd196
) {
1045
173
    CmdArgs.push_back("-z");
1046
173
    CmdArgs.push_back(as_needed ? 
"ignore"83
:
"record"90
);
1047
5.61k
  } else {
1048
5.61k
    CmdArgs.push_back(as_needed ? 
"--as-needed"2.63k
:
"--no-as-needed"2.97k
);
1049
5.61k
  }
1050
5.78k
}
1051
1052
void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
1053
                                     const llvm::opt::ArgList &Args,
1054
328
                                     ArgStringList &CmdArgs) {
1055
  // Force linking against the system libraries sanitizers depends on
1056
  // (see PR15823 why this is necessary).
1057
328
  addAsNeededOption(TC, Args, CmdArgs, false);
1058
  // There's no libpthread or librt on RTEMS & Android.
1059
328
  if (TC.getTriple().getOS() != llvm::Triple::RTEMS &&
1060
328
      !TC.getTriple().isAndroid() && 
!TC.getTriple().isOHOSFamily()325
) {
1061
321
    CmdArgs.push_back("-lpthread");
1062
321
    if (!TC.getTriple().isOSOpenBSD())
1063
320
      CmdArgs.push_back("-lrt");
1064
321
  }
1065
328
  CmdArgs.push_back("-lm");
1066
  // There's no libdl on all OSes.
1067
328
  if (!TC.getTriple().isOSFreeBSD() && 
!TC.getTriple().isOSNetBSD()324
&&
1068
328
      
!TC.getTriple().isOSOpenBSD()306
&&
1069
328
      
TC.getTriple().getOS() != llvm::Triple::RTEMS305
)
1070
305
    CmdArgs.push_back("-ldl");
1071
  // Required for backtrace on some OSes
1072
328
  if (TC.getTriple().isOSFreeBSD() ||
1073
328
      
TC.getTriple().isOSNetBSD()324
||
1074
328
      
TC.getTriple().isOSOpenBSD()306
)
1075
23
    CmdArgs.push_back("-lexecinfo");
1076
  // There is no libresolv on Android, FreeBSD, OpenBSD, etc. On musl
1077
  // libresolv.a, even if exists, is an empty archive to satisfy POSIX -lresolv
1078
  // requirement.
1079
328
  if (TC.getTriple().isOSLinux() && 
!TC.getTriple().isAndroid()293
&&
1080
328
      
!TC.getTriple().isMusl()290
)
1081
290
    CmdArgs.push_back("-lresolv");
1082
328
}
1083
1084
static void
1085
collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
1086
                         SmallVectorImpl<StringRef> &SharedRuntimes,
1087
                         SmallVectorImpl<StringRef> &StaticRuntimes,
1088
                         SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
1089
                         SmallVectorImpl<StringRef> &HelperStaticRuntimes,
1090
2.02k
                         SmallVectorImpl<StringRef> &RequiredSymbols) {
1091
2.02k
  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
1092
  // Collect shared runtimes.
1093
2.02k
  if (SanArgs.needsSharedRt()) {
1094
215
    if (SanArgs.needsAsanRt() && 
SanArgs.linkRuntimes()22
) {
1095
22
      SharedRuntimes.push_back("asan");
1096
22
      if (!Args.hasArg(options::OPT_shared) && 
!TC.getTriple().isAndroid()18
)
1097
13
        HelperStaticRuntimes.push_back("asan-preinit");
1098
22
    }
1099
215
    if (SanArgs.needsMemProfRt() && 
SanArgs.linkRuntimes()0
) {
1100
0
      SharedRuntimes.push_back("memprof");
1101
0
      if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
1102
0
        HelperStaticRuntimes.push_back("memprof-preinit");
1103
0
    }
1104
215
    if (SanArgs.needsUbsanRt() && 
SanArgs.linkRuntimes()7
) {
1105
7
      if (SanArgs.requiresMinimalRuntime())
1106
0
        SharedRuntimes.push_back("ubsan_minimal");
1107
7
      else
1108
7
        SharedRuntimes.push_back("ubsan_standalone");
1109
7
    }
1110
215
    if (SanArgs.needsScudoRt() && 
SanArgs.linkRuntimes()8
) {
1111
8
      SharedRuntimes.push_back("scudo_standalone");
1112
8
    }
1113
215
    if (SanArgs.needsTsanRt() && 
SanArgs.linkRuntimes()0
)
1114
0
      SharedRuntimes.push_back("tsan");
1115
215
    if (SanArgs.needsHwasanRt() && 
SanArgs.linkRuntimes()9
) {
1116
9
      if (SanArgs.needsHwasanAliasesRt())
1117
0
        SharedRuntimes.push_back("hwasan_aliases");
1118
9
      else
1119
9
        SharedRuntimes.push_back("hwasan");
1120
9
      if (!Args.hasArg(options::OPT_shared))
1121
7
        HelperStaticRuntimes.push_back("hwasan-preinit");
1122
9
    }
1123
215
  }
1124
1125
  // The stats_client library is also statically linked into DSOs.
1126
2.02k
  if (SanArgs.needsStatsRt() && 
SanArgs.linkRuntimes()1
)
1127
1
    StaticRuntimes.push_back("stats_client");
1128
1129
  // Always link the static runtime regardless of DSO or executable.
1130
2.02k
  if (SanArgs.needsAsanRt())
1131
112
    HelperStaticRuntimes.push_back("asan_static");
1132
1133
  // Collect static runtimes.
1134
2.02k
  if (Args.hasArg(options::OPT_shared)) {
1135
    // Don't link static runtimes into DSOs.
1136
60
    return;
1137
60
  }
1138
1139
  // Each static runtime that has a DSO counterpart above is excluded below,
1140
  // but runtimes that exist only as static are not affected by needsSharedRt.
1141
1142
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsAsanRt()1.77k
&&
SanArgs.linkRuntimes()89
) {
1143
88
    StaticRuntimes.push_back("asan");
1144
88
    if (SanArgs.linkCXXRuntimes())
1145
2
      StaticRuntimes.push_back("asan_cxx");
1146
88
  }
1147
1148
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsMemProfRt()1.77k
&&
1149
1.96k
      
SanArgs.linkRuntimes()3
) {
1150
3
    StaticRuntimes.push_back("memprof");
1151
3
    if (SanArgs.linkCXXRuntimes())
1152
3
      StaticRuntimes.push_back("memprof_cxx");
1153
3
  }
1154
1155
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsHwasanRt()1.77k
&&
SanArgs.linkRuntimes()16
) {
1156
16
    if (SanArgs.needsHwasanAliasesRt()) {
1157
1
      StaticRuntimes.push_back("hwasan_aliases");
1158
1
      if (SanArgs.linkCXXRuntimes())
1159
0
        StaticRuntimes.push_back("hwasan_aliases_cxx");
1160
15
    } else {
1161
15
      StaticRuntimes.push_back("hwasan");
1162
15
      if (SanArgs.linkCXXRuntimes())
1163
0
        StaticRuntimes.push_back("hwasan_cxx");
1164
15
    }
1165
16
  }
1166
1.96k
  if (SanArgs.needsDfsanRt() && 
SanArgs.linkRuntimes()4
)
1167
4
    StaticRuntimes.push_back("dfsan");
1168
1.96k
  if (SanArgs.needsLsanRt() && 
SanArgs.linkRuntimes()29
)
1169
28
    StaticRuntimes.push_back("lsan");
1170
1.96k
  if (SanArgs.needsMsanRt() && 
SanArgs.linkRuntimes()31
) {
1171
30
    StaticRuntimes.push_back("msan");
1172
30
    if (SanArgs.linkCXXRuntimes())
1173
2
      StaticRuntimes.push_back("msan_cxx");
1174
30
  }
1175
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsTsanRt()1.77k
&&
1176
1.96k
      
SanArgs.linkRuntimes()22
) {
1177
21
    StaticRuntimes.push_back("tsan");
1178
21
    if (SanArgs.linkCXXRuntimes())
1179
2
      StaticRuntimes.push_back("tsan_cxx");
1180
21
  }
1181
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsUbsanRt()1.77k
&&
SanArgs.linkRuntimes()104
) {
1182
103
    if (SanArgs.requiresMinimalRuntime()) {
1183
7
      StaticRuntimes.push_back("ubsan_minimal");
1184
96
    } else {
1185
96
      StaticRuntimes.push_back("ubsan_standalone");
1186
96
      if (SanArgs.linkCXXRuntimes())
1187
2
        StaticRuntimes.push_back("ubsan_standalone_cxx");
1188
96
    }
1189
103
  }
1190
1.96k
  if (SanArgs.needsSafeStackRt() && 
SanArgs.linkRuntimes()12
) {
1191
12
    NonWholeStaticRuntimes.push_back("safestack");
1192
12
    RequiredSymbols.push_back("__safestack_init");
1193
12
  }
1194
1.96k
  if (!(SanArgs.needsSharedRt() && 
SanArgs.needsUbsanRt()188
&&
SanArgs.linkRuntimes()6
)) {
1195
1.95k
    if (SanArgs.needsCfiRt() && 
SanArgs.linkRuntimes()1
)
1196
1
      StaticRuntimes.push_back("cfi");
1197
1.95k
    if (SanArgs.needsCfiDiagRt() && 
SanArgs.linkRuntimes()1
) {
1198
1
      StaticRuntimes.push_back("cfi_diag");
1199
1
      if (SanArgs.linkCXXRuntimes())
1200
0
        StaticRuntimes.push_back("ubsan_standalone_cxx");
1201
1
    }
1202
1.95k
  }
1203
1.96k
  if (SanArgs.needsStatsRt() && 
SanArgs.linkRuntimes()1
) {
1204
1
    NonWholeStaticRuntimes.push_back("stats");
1205
1
    RequiredSymbols.push_back("__sanitizer_stats_register");
1206
1
  }
1207
1.96k
  if (!SanArgs.needsSharedRt() && 
SanArgs.needsScudoRt()1.77k
&&
SanArgs.linkRuntimes()25
) {
1208
25
    StaticRuntimes.push_back("scudo_standalone");
1209
25
    if (SanArgs.linkCXXRuntimes())
1210
0
      StaticRuntimes.push_back("scudo_standalone_cxx");
1211
25
  }
1212
1.96k
}
1213
1214
// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
1215
// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
1216
bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
1217
2.02k
                                 ArgStringList &CmdArgs) {
1218
2.02k
  SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
1219
2.02k
      NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
1220
2.02k
  collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
1221
2.02k
                           NonWholeStaticRuntimes, HelperStaticRuntimes,
1222
2.02k
                           RequiredSymbols);
1223
1224
2.02k
  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
1225
  // Inject libfuzzer dependencies.
1226
2.02k
  if (SanArgs.needsFuzzer() && 
SanArgs.linkRuntimes()9
&&
1227
2.02k
      
!Args.hasArg(options::OPT_shared)9
) {
1228
1229
8
    addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
1230
8
    if (SanArgs.needsFuzzerInterceptors())
1231
8
      addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
1232
8
                          true);
1233
8
    if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) {
1234
8
      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
1235
8
                                 
!Args.hasArg(options::OPT_static)2
;
1236
8
      if (OnlyLibstdcxxStatic)
1237
2
        CmdArgs.push_back("-Bstatic");
1238
8
      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
1239
8
      if (OnlyLibstdcxxStatic)
1240
2
        CmdArgs.push_back("-Bdynamic");
1241
8
    }
1242
8
  }
1243
1244
2.02k
  for (auto RT : SharedRuntimes)
1245
46
    addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
1246
2.02k
  for (auto RT : HelperStaticRuntimes)
1247
132
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
1248
2.02k
  bool AddExportDynamic = false;
1249
2.02k
  for (auto RT : StaticRuntimes) {
1250
332
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
1251
332
    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
1252
332
  }
1253
2.02k
  for (auto RT : NonWholeStaticRuntimes) {
1254
13
    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
1255
13
    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
1256
13
  }
1257
2.02k
  for (auto S : RequiredSymbols) {
1258
13
    CmdArgs.push_back("-u");
1259
13
    CmdArgs.push_back(Args.MakeArgString(S));
1260
13
  }
1261
  // If there is a static runtime with no dynamic list, force all the symbols
1262
  // to be dynamic to be sure we export sanitizer interface functions.
1263
2.02k
  if (AddExportDynamic)
1264
307
    CmdArgs.push_back("--export-dynamic");
1265
1266
2.02k
  if (SanArgs.hasCrossDsoCfi() && 
!AddExportDynamic4
)
1267
2
    CmdArgs.push_back("--export-dynamic-symbol=__cfi_check");
1268
1269
2.02k
  if (SanArgs.hasMemTag()) {
1270
13
    if (!TC.getTriple().isAndroid()) {
1271
2
      TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1272
2
          << "-fsanitize=memtag*" << TC.getTriple().str();
1273
2
    }
1274
13
    CmdArgs.push_back(
1275
13
        Args.MakeArgString("--android-memtag-mode=" + SanArgs.getMemtagMode()));
1276
13
    if (SanArgs.hasMemtagHeap())
1277
11
      CmdArgs.push_back("--android-memtag-heap");
1278
13
    if (SanArgs.hasMemtagStack())
1279
10
      CmdArgs.push_back("--android-memtag-stack");
1280
13
  }
1281
1282
2.02k
  return !StaticRuntimes.empty() || 
!NonWholeStaticRuntimes.empty()1.70k
;
1283
2.02k
}
1284
1285
1.95k
bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) {
1286
1.95k
  if (Args.hasArg(options::OPT_shared))
1287
54
    return false;
1288
1289
1.90k
  if (TC.getXRayArgs().needsXRayRt()) {
1290
17
    CmdArgs.push_back("--whole-archive");
1291
17
    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray"));
1292
17
    for (const auto &Mode : TC.getXRayArgs().modeList())
1293
23
      CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode));
1294
17
    CmdArgs.push_back("--no-whole-archive");
1295
17
    return true;
1296
17
  }
1297
1298
1.88k
  return false;
1299
1.90k
}
1300
1301
void tools::linkXRayRuntimeDeps(const ToolChain &TC,
1302
                                const llvm::opt::ArgList &Args,
1303
15
                                ArgStringList &CmdArgs) {
1304
15
  addAsNeededOption(TC, Args, CmdArgs, false);
1305
15
  CmdArgs.push_back("-lpthread");
1306
15
  if (!TC.getTriple().isOSOpenBSD())
1307
15
    CmdArgs.push_back("-lrt");
1308
15
  CmdArgs.push_back("-lm");
1309
1310
15
  if (!TC.getTriple().isOSFreeBSD() &&
1311
15
      !TC.getTriple().isOSNetBSD() &&
1312
15
      !TC.getTriple().isOSOpenBSD())
1313
15
    CmdArgs.push_back("-ldl");
1314
15
}
1315
1316
6.46k
bool tools::areOptimizationsEnabled(const ArgList &Args) {
1317
  // Find the last -O arg and see if it is non-zero.
1318
6.46k
  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1319
250
    return !A->getOption().matches(options::OPT_O0);
1320
  // Defaults to -O0.
1321
6.21k
  return false;
1322
6.46k
}
1323
1324
const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args,
1325
                                  const InputInfo &Input,
1326
50
                                  const InputInfo &Output) {
1327
50
  auto AddPostfix = [JA](auto &F) {
1328
47
    if (JA.getOffloadingDeviceKind() == Action::OFK_HIP)
1329
8
      F += (Twine("_") + JA.getOffloadingArch()).str();
1330
47
    F += ".dwo";
1331
47
  };
1332
50
  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
1333
9
    if (StringRef(A->getValue()) == "single" && 
Output.isFilename()4
)
1334
3
      return Args.MakeArgString(Output.getFilename());
1335
1336
47
  SmallString<128> T;
1337
47
  if (const Arg *A = Args.getLastArg(options::OPT_dumpdir)) {
1338
13
    T = A->getValue();
1339
34
  } else {
1340
34
    Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
1341
34
    if (FinalOutput && 
Args.hasArg(options::OPT_c)2
) {
1342
2
      T = FinalOutput->getValue();
1343
2
      llvm::sys::path::remove_filename(T);
1344
2
      llvm::sys::path::append(T,
1345
2
                              llvm::sys::path::stem(FinalOutput->getValue()));
1346
2
      AddPostfix(T);
1347
2
      return Args.MakeArgString(T);
1348
2
    }
1349
34
  }
1350
1351
45
  T += llvm::sys::path::stem(Input.getBaseInput());
1352
45
  AddPostfix(T);
1353
45
  return Args.MakeArgString(T);
1354
47
}
1355
1356
void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
1357
                           const JobAction &JA, const ArgList &Args,
1358
1
                           const InputInfo &Output, const char *OutFile) {
1359
1
  ArgStringList ExtractArgs;
1360
1
  ExtractArgs.push_back("--extract-dwo");
1361
1362
1
  ArgStringList StripArgs;
1363
1
  StripArgs.push_back("--strip-dwo");
1364
1365
  // Grabbing the output of the earlier compile step.
1366
1
  StripArgs.push_back(Output.getFilename());
1367
1
  ExtractArgs.push_back(Output.getFilename());
1368
1
  ExtractArgs.push_back(OutFile);
1369
1370
1
  const char *Exec =
1371
1
      Args.MakeArgString(TC.GetProgramPath(CLANG_DEFAULT_OBJCOPY));
1372
1
  InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
1373
1374
  // First extract the dwo sections.
1375
1
  C.addCommand(std::make_unique<Command>(JA, T,
1376
1
                                         ResponseFileSupport::AtFileCurCP(),
1377
1
                                         Exec, ExtractArgs, II, Output));
1378
1379
  // Then remove them from the original .o file.
1380
1
  C.addCommand(std::make_unique<Command>(
1381
1
      JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II, Output));
1382
1
}
1383
1384
// Claim options we don't want to warn if they are unused. We do this for
1385
// options that build systems might add but are unused when assembling or only
1386
// running the preprocessor for example.
1387
48.7k
void tools::claimNoWarnArgs(const ArgList &Args) {
1388
  // Don't warn about unused -f(no-)?lto.  This can happen when we're
1389
  // preprocessing, precompiling or assembling.
1390
48.7k
  Args.ClaimAllArgs(options::OPT_flto_EQ);
1391
48.7k
  Args.ClaimAllArgs(options::OPT_flto);
1392
48.7k
  Args.ClaimAllArgs(options::OPT_fno_lto);
1393
48.7k
}
1394
1395
47.6k
Arg *tools::getLastCSProfileGenerateArg(const ArgList &Args) {
1396
47.6k
  auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
1397
47.6k
                                           options::OPT_fcs_profile_generate_EQ,
1398
47.6k
                                           options::OPT_fno_profile_generate);
1399
47.6k
  if (CSPGOGenerateArg &&
1400
47.6k
      
CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)17
)
1401
7
    CSPGOGenerateArg = nullptr;
1402
1403
47.6k
  return CSPGOGenerateArg;
1404
47.6k
}
1405
1406
47.6k
Arg *tools::getLastProfileUseArg(const ArgList &Args) {
1407
47.6k
  auto *ProfileUseArg = Args.getLastArg(
1408
47.6k
      options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
1409
47.6k
      options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
1410
47.6k
      options::OPT_fno_profile_instr_use);
1411
1412
47.6k
  if (ProfileUseArg &&
1413
47.6k
      
ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use)59
)
1414
4
    ProfileUseArg = nullptr;
1415
1416
47.6k
  return ProfileUseArg;
1417
47.6k
}
1418
1419
96.0k
Arg *tools::getLastProfileSampleUseArg(const ArgList &Args) {
1420
96.0k
  auto *ProfileSampleUseArg = Args.getLastArg(
1421
96.0k
      options::OPT_fprofile_sample_use, options::OPT_fprofile_sample_use_EQ,
1422
96.0k
      options::OPT_fauto_profile, options::OPT_fauto_profile_EQ,
1423
96.0k
      options::OPT_fno_profile_sample_use, options::OPT_fno_auto_profile);
1424
1425
96.0k
  if (ProfileSampleUseArg &&
1426
96.0k
      
(21
ProfileSampleUseArg->getOption().matches(
1427
21
           options::OPT_fno_profile_sample_use) ||
1428
21
       
ProfileSampleUseArg->getOption().matches(options::OPT_fno_auto_profile)17
))
1429
4
    return nullptr;
1430
1431
96.0k
  return Args.getLastArg(options::OPT_fprofile_sample_use_EQ,
1432
96.0k
                         options::OPT_fauto_profile_EQ);
1433
96.0k
}
1434
1435
48.4k
const char *tools::RelocationModelName(llvm::Reloc::Model Model) {
1436
48.4k
  switch (Model) {
1437
15.3k
  case llvm::Reloc::Static:
1438
15.3k
    return "static";
1439
33.0k
  case llvm::Reloc::PIC_:
1440
33.0k
    return "pic";
1441
9
  case llvm::Reloc::DynamicNoPIC:
1442
9
    return "dynamic-no-pic";
1443
11
  case llvm::Reloc::ROPI:
1444
11
    return "ropi";
1445
6
  case llvm::Reloc::RWPI:
1446
6
    return "rwpi";
1447
5
  case llvm::Reloc::ROPI_RWPI:
1448
5
    return "ropi-rwpi";
1449
48.4k
  }
1450
0
  llvm_unreachable("Unknown Reloc::Model kind");
1451
0
}
1452
1453
/// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
1454
/// smooshes them together with platform defaults, to decide whether
1455
/// this compile should be using PIC mode or not. Returns a tuple of
1456
/// (RelocationModel, PICLevel, IsPIE).
1457
std::tuple<llvm::Reloc::Model, unsigned, bool>
1458
49.3k
tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
1459
49.3k
  const llvm::Triple &EffectiveTriple = ToolChain.getEffectiveTriple();
1460
49.3k
  const llvm::Triple &Triple = ToolChain.getTriple();
1461
1462
49.3k
  bool PIE = ToolChain.isPIEDefault(Args);
1463
49.3k
  bool PIC = PIE || 
ToolChain.isPICDefault()43.3k
;
1464
  // The Darwin/MachO default to use PIC does not apply when using -static.
1465
49.3k
  if (Triple.isOSBinFormatMachO() && 
Args.hasArg(options::OPT_static)18.0k
)
1466
27
    PIE = PIC = false;
1467
49.3k
  bool IsPICLevelTwo = PIC;
1468
1469
49.3k
  bool KernelOrKext =
1470
49.3k
      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
1471
1472
  // Android-specific defaults for PIC/PIE
1473
49.3k
  if (Triple.isAndroid()) {
1474
210
    switch (Triple.getArch()) {
1475
87
    case llvm::Triple::arm:
1476
87
    case llvm::Triple::armeb:
1477
89
    case llvm::Triple::thumb:
1478
89
    case llvm::Triple::thumbeb:
1479
166
    case llvm::Triple::aarch64:
1480
166
    case llvm::Triple::mips:
1481
166
    case llvm::Triple::mipsel:
1482
166
    case llvm::Triple::mips64:
1483
166
    case llvm::Triple::mips64el:
1484
166
      PIC = true; // "-fpic"
1485
166
      break;
1486
1487
15
    case llvm::Triple::x86:
1488
32
    case llvm::Triple::x86_64:
1489
32
      PIC = true; // "-fPIC"
1490
32
      IsPICLevelTwo = true;
1491
32
      break;
1492
1493
12
    default:
1494
12
      break;
1495
210
    }
1496
210
  }
1497
1498
  // OHOS-specific defaults for PIC/PIE
1499
49.3k
  if (Triple.isOHOSFamily() && 
Triple.getArch() == llvm::Triple::aarch6440
)
1500
3
    PIC = true;
1501
1502
  // OpenBSD-specific defaults for PIE
1503
49.3k
  if (Triple.isOSOpenBSD()) {
1504
137
    switch (ToolChain.getArch()) {
1505
13
    case llvm::Triple::arm:
1506
22
    case llvm::Triple::aarch64:
1507
36
    case llvm::Triple::mips64:
1508
48
    case llvm::Triple::mips64el:
1509
88
    case llvm::Triple::x86:
1510
113
    case llvm::Triple::x86_64:
1511
113
      IsPICLevelTwo = false; // "-fpie"
1512
113
      break;
1513
1514
4
    case llvm::Triple::ppc:
1515
16
    case llvm::Triple::sparcv9:
1516
16
      IsPICLevelTwo = true; // "-fPIE"
1517
16
      break;
1518
1519
8
    default:
1520
8
      break;
1521
137
    }
1522
137
  }
1523
1524
  // The last argument relating to either PIC or PIE wins, and no
1525
  // other argument is used. If the last argument is any flavor of the
1526
  // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
1527
  // option implicitly enables PIC at the same level.
1528
49.3k
  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
1529
49.3k
                                    options::OPT_fpic, options::OPT_fno_pic,
1530
49.3k
                                    options::OPT_fPIE, options::OPT_fno_PIE,
1531
49.3k
                                    options::OPT_fpie, options::OPT_fno_pie);
1532
49.3k
  if (Triple.isOSWindows() && 
!Triple.isOSCygMing()8.82k
&&
LastPICArg8.69k
&&
1533
49.3k
      LastPICArg == Args.getLastArg(options::OPT_fPIC, options::OPT_fpic,
1534
32
                                    options::OPT_fPIE, options::OPT_fpie)) {
1535
16
    ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1536
16
        << LastPICArg->getSpelling() << Triple.str();
1537
16
    if (Triple.getArch() == llvm::Triple::x86_64)
1538
8
      return std::make_tuple(llvm::Reloc::PIC_, 2U, false);
1539
8
    return std::make_tuple(llvm::Reloc::Static, 0U, false);
1540
16
  }
1541
1542
  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
1543
  // is forced, then neither PIC nor PIE flags will have no effect.
1544
49.3k
  if (!ToolChain.isPICDefaultForced()) {
1545
22.1k
    if (LastPICArg) {
1546
465
      Option O = LastPICArg->getOption();
1547
465
      if (O.matches(options::OPT_fPIC) || 
O.matches(options::OPT_fpic)392
||
1548
465
          
O.matches(options::OPT_fPIE)362
||
O.matches(options::OPT_fpie)342
) {
1549
140
        PIE = O.matches(options::OPT_fPIE) || 
O.matches(options::OPT_fpie)120
;
1550
140
        PIC =
1551
140
            PIE || 
O.matches(options::OPT_fPIC)103
||
O.matches(options::OPT_fpic)30
;
1552
140
        IsPICLevelTwo =
1553
140
            O.matches(options::OPT_fPIE) || 
O.matches(options::OPT_fPIC)120
;
1554
325
      } else {
1555
325
        PIE = PIC = false;
1556
325
        if (EffectiveTriple.isPS()) {
1557
40
          Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
1558
40
          StringRef Model = ModelArg ? 
ModelArg->getValue()8
:
""32
;
1559
40
          if (Model != "kernel") {
1560
32
            PIC = true;
1561
32
            ToolChain.getDriver().Diag(diag::warn_drv_ps_force_pic)
1562
32
                << LastPICArg->getSpelling()
1563
32
                << (EffectiveTriple.isPS4() ? 
"PS4"16
:
"PS5"16
);
1564
32
          }
1565
40
        }
1566
325
      }
1567
465
    }
1568
22.1k
  }
1569
1570
  // Introduce a Darwin and PS4/PS5-specific hack. If the default is PIC, but
1571
  // the PIC level would've been set to level 1, force it back to level 2 PIC
1572
  // instead.
1573
49.3k
  if (PIC && 
(33.4k
Triple.isOSDarwin()33.4k
||
EffectiveTriple.isPS()15.5k
))
1574
18.2k
    IsPICLevelTwo |= ToolChain.isPICDefault();
1575
1576
  // This kernel flags are a trump-card: they will disable PIC/PIE
1577
  // generation, independent of the argument order.
1578
49.3k
  if (KernelOrKext &&
1579
49.3k
      
(30
(30
!EffectiveTriple.isiOS()30
||
EffectiveTriple.isOSVersionLT(6)8
) &&
1580
30
       
!EffectiveTriple.isWatchOS()26
&&
!EffectiveTriple.isDriverKit()25
))
1581
24
    PIC = PIE = false;
1582
1583
49.3k
  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
1584
    // This is a very special mode. It trumps the other modes, almost no one
1585
    // uses it, and it isn't even valid on any OS but Darwin.
1586
9
    if (!Triple.isOSDarwin())
1587
3
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1588
3
          << A->getSpelling() << Triple.str();
1589
1590
    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
1591
1592
    // Only a forced PIC mode can cause the actual compile to have PIC defines
1593
    // etc., no flags are sufficient. This behavior was selected to closely
1594
    // match that of llvm-gcc and Apple GCC before that.
1595
9
    PIC = ToolChain.isPICDefault() && 
ToolChain.isPICDefaultForced()8
;
1596
1597
9
    return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 
2U3
:
0U6
, false);
1598
9
  }
1599
1600
49.3k
  bool EmbeddedPISupported;
1601
49.3k
  switch (Triple.getArch()) {
1602
1.98k
    case llvm::Triple::arm:
1603
2.14k
    case llvm::Triple::armeb:
1604
2.21k
    case llvm::Triple::thumb:
1605
2.23k
    case llvm::Triple::thumbeb:
1606
2.23k
      EmbeddedPISupported = true;
1607
2.23k
      break;
1608
47.0k
    default:
1609
47.0k
      EmbeddedPISupported = false;
1610
47.0k
      break;
1611
49.3k
  }
1612
1613
49.3k
  bool ROPI = false, RWPI = false;
1614
49.3k
  Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
1615
49.3k
  if (LastROPIArg && 
LastROPIArg->getOption().matches(options::OPT_fropi)20
) {
1616
20
    if (!EmbeddedPISupported)
1617
2
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1618
2
          << LastROPIArg->getSpelling() << Triple.str();
1619
20
    ROPI = true;
1620
20
  }
1621
49.3k
  Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
1622
49.3k
  if (LastRWPIArg && 
LastRWPIArg->getOption().matches(options::OPT_frwpi)15
) {
1623
15
    if (!EmbeddedPISupported)
1624
2
      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1625
2
          << LastRWPIArg->getSpelling() << Triple.str();
1626
15
    RWPI = true;
1627
15
  }
1628
1629
  // ROPI and RWPI are not compatible with PIC or PIE.
1630
49.3k
  if ((ROPI || 
RWPI49.2k
) &&
(28
PIC28
||
PIE22
))
1631
6
    ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
1632
1633
49.3k
  if (Triple.isMIPS()) {
1634
977
    StringRef CPUName;
1635
977
    StringRef ABIName;
1636
977
    mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1637
    // When targeting the N64 ABI, PIC is the default, except in the case
1638
    // when the -mno-abicalls option is used. In that case we exit
1639
    // at next check regardless of PIC being set below.
1640
977
    if (ABIName == "n64")
1641
262
      PIC = true;
1642
    // When targettng MIPS with -mno-abicalls, it's always static.
1643
977
    if(Args.hasArg(options::OPT_mno_abicalls))
1644
77
      return std::make_tuple(llvm::Reloc::Static, 0U, false);
1645
    // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot,
1646
    // does not use PIC level 2 for historical reasons.
1647
900
    IsPICLevelTwo = false;
1648
900
  }
1649
1650
49.2k
  if (PIC)
1651
33.5k
    return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 
2U32.6k
:
1U805
, PIE);
1652
1653
15.7k
  llvm::Reloc::Model RelocM = llvm::Reloc::Static;
1654
15.7k
  if (ROPI && 
RWPI16
)
1655
5
    RelocM = llvm::Reloc::ROPI_RWPI;
1656
15.7k
  else if (ROPI)
1657
11
    RelocM = llvm::Reloc::ROPI;
1658
15.7k
  else if (RWPI)
1659
6
    RelocM = llvm::Reloc::RWPI;
1660
1661
15.7k
  return std::make_tuple(RelocM, 0U, false);
1662
49.2k
}
1663
1664
// `-falign-functions` indicates that the functions should be aligned to a
1665
// 16-byte boundary.
1666
//
1667
// `-falign-functions=1` is the same as `-fno-align-functions`.
1668
//
1669
// The scalar `n` in `-falign-functions=n` must be an integral value between
1670
// [0, 65536].  If the value is not a power-of-two, it will be rounded up to
1671
// the nearest power-of-two.
1672
//
1673
// If we return `0`, the frontend will default to the backend's preferred
1674
// alignment.
1675
//
1676
// NOTE: icc only allows values between [0, 4096].  icc uses `-falign-functions`
1677
// to mean `-falign-functions=16`.  GCC defaults to the backend's preferred
1678
// alignment.  For unaligned functions, we default to the backend's preferred
1679
// alignment.
1680
unsigned tools::ParseFunctionAlignment(const ToolChain &TC,
1681
47.9k
                                       const ArgList &Args) {
1682
47.9k
  const Arg *A = Args.getLastArg(options::OPT_falign_functions,
1683
47.9k
                                 options::OPT_falign_functions_EQ,
1684
47.9k
                                 options::OPT_fno_align_functions);
1685
47.9k
  if (!A || 
A->getOption().matches(options::OPT_fno_align_functions)8
)
1686
47.9k
    return 0;
1687
1688
6
  if (A->getOption().matches(options::OPT_falign_functions))
1689
1
    return 0;
1690
1691
5
  unsigned Value = 0;
1692
5
  if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536)
1693
2
    TC.getDriver().Diag(diag::err_drv_invalid_int_value)
1694
2
        << A->getAsString(Args) << A->getValue();
1695
5
  return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : 
Value0
;
1696
6
}
1697
1698
void tools::addDebugInfoKind(
1699
48.4k
    ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind) {
1700
48.4k
  switch (DebugInfoKind) {
1701
11
  case llvm::codegenoptions::DebugDirectivesOnly:
1702
11
    CmdArgs.push_back("-debug-info-kind=line-directives-only");
1703
11
    break;
1704
57
  case llvm::codegenoptions::DebugLineTablesOnly:
1705
57
    CmdArgs.push_back("-debug-info-kind=line-tables-only");
1706
57
    break;
1707
349
  case llvm::codegenoptions::DebugInfoConstructor:
1708
349
    CmdArgs.push_back("-debug-info-kind=constructor");
1709
349
    break;
1710
0
  case llvm::codegenoptions::LimitedDebugInfo:
1711
0
    CmdArgs.push_back("-debug-info-kind=limited");
1712
0
    break;
1713
3.00k
  case llvm::codegenoptions::FullDebugInfo:
1714
3.00k
    CmdArgs.push_back("-debug-info-kind=standalone");
1715
3.00k
    break;
1716
1
  case llvm::codegenoptions::UnusedTypeInfo:
1717
1
    CmdArgs.push_back("-debug-info-kind=unused-types");
1718
1
    break;
1719
45.0k
  default:
1720
45.0k
    break;
1721
48.4k
  }
1722
48.4k
}
1723
1724
// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
1725
// to the corresponding DebugInfoKind.
1726
132
llvm::codegenoptions::DebugInfoKind tools::debugLevelToInfoKind(const Arg &A) {
1727
132
  assert(A.getOption().matches(options::OPT_gN_Group) &&
1728
132
         "Not a -g option that specifies a debug-info level");
1729
132
  if (A.getOption().matches(options::OPT_g0) ||
1730
132
      
A.getOption().matches(options::OPT_ggdb0)106
)
1731
30
    return llvm::codegenoptions::NoDebugInfo;
1732
102
  if (A.getOption().matches(options::OPT_gline_tables_only) ||
1733
102
      
A.getOption().matches(options::OPT_ggdb1)85
)
1734
22
    return llvm::codegenoptions::DebugLineTablesOnly;
1735
80
  if (A.getOption().matches(options::OPT_gline_directives_only))
1736
6
    return llvm::codegenoptions::DebugDirectivesOnly;
1737
74
  return llvm::codegenoptions::DebugInfoConstructor;
1738
80
}
1739
1740
static unsigned ParseDebugDefaultVersion(const ToolChain &TC,
1741
3.77k
                                         const ArgList &Args) {
1742
3.77k
  const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version);
1743
1744
3.77k
  if (!A)
1745
3.76k
    return 0;
1746
1747
15
  unsigned Value = 0;
1748
15
  if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 5 ||
1749
15
      Value < 2)
1750
0
    TC.getDriver().Diag(diag::err_drv_invalid_int_value)
1751
0
        << A->getAsString(Args) << A->getValue();
1752
15
  return Value;
1753
3.77k
}
1754
1755
79
unsigned tools::DwarfVersionNum(StringRef ArgValue) {
1756
79
  return llvm::StringSwitch<unsigned>(ArgValue)
1757
79
      .Case("-gdwarf-2", 2)
1758
79
      .Case("-gdwarf-3", 3)
1759
79
      .Case("-gdwarf-4", 4)
1760
79
      .Case("-gdwarf-5", 5)
1761
79
      .Default(0);
1762
79
}
1763
1764
51.7k
const Arg *tools::getDwarfNArg(const ArgList &Args) {
1765
51.7k
  return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
1766
51.7k
                         options::OPT_gdwarf_4, options::OPT_gdwarf_5,
1767
51.7k
                         options::OPT_gdwarf);
1768
51.7k
}
1769
1770
unsigned tools::getDwarfVersion(const ToolChain &TC,
1771
3.77k
                                const llvm::opt::ArgList &Args) {
1772
3.77k
  unsigned DwarfVersion = ParseDebugDefaultVersion(TC, Args);
1773
3.77k
  if (const Arg *GDwarfN = getDwarfNArg(Args))
1774
76
    if (int N = DwarfVersionNum(GDwarfN->getSpelling()))
1775
64
      DwarfVersion = N;
1776
3.77k
  if (DwarfVersion == 0) {
1777
3.70k
    DwarfVersion = TC.GetDefaultDwarfVersion();
1778
3.70k
    assert(DwarfVersion && "toolchain default DWARF version must be nonzero");
1779
3.70k
  }
1780
3.77k
  return DwarfVersion;
1781
3.77k
}
1782
1783
void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
1784
172
                             ArgStringList &CmdArgs) {
1785
172
  llvm::Reloc::Model RelocationModel;
1786
172
  unsigned PICLevel;
1787
172
  bool IsPIE;
1788
172
  std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args);
1789
1790
172
  if (RelocationModel != llvm::Reloc::Static)
1791
60
    CmdArgs.push_back("-KPIC");
1792
172
}
1793
1794
/// Determine whether Objective-C automated reference counting is
1795
/// enabled.
1796
51.3k
bool tools::isObjCAutoRefCount(const ArgList &Args) {
1797
51.3k
  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
1798
51.3k
}
1799
1800
enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
1801
1802
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
1803
6.05k
                                const ArgList &Args) {
1804
6.05k
  if (Args.hasArg(options::OPT_static_libgcc) ||
1805
6.05k
      
Args.hasArg(options::OPT_static)6.03k
||
Args.hasArg(options::OPT_static_pie)5.99k
||
1806
      // The Android NDK only provides libunwind.a, not libunwind.so.
1807
6.05k
      
TC.getTriple().isAndroid()5.98k
)
1808
340
    return LibGccType::StaticLibGcc;
1809
5.71k
  if (Args.hasArg(options::OPT_shared_libgcc))
1810
14
    return LibGccType::SharedLibGcc;
1811
5.70k
  return LibGccType::UnspecifiedLibGcc;
1812
5.71k
}
1813
1814
// Gcc adds libgcc arguments in various ways:
1815
//
1816
// gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
1817
// g++ <none>:                       -lgcc_s               -lgcc
1818
// gcc shared:                       -lgcc_s               -lgcc
1819
// g++ shared:                       -lgcc_s               -lgcc
1820
// gcc static:     -lgcc             -lgcc_eh
1821
// g++ static:     -lgcc             -lgcc_eh
1822
// gcc static-pie: -lgcc             -lgcc_eh
1823
// g++ static-pie: -lgcc             -lgcc_eh
1824
//
1825
// Also, certain targets need additional adjustments.
1826
1827
static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
1828
3.56k
                             ArgStringList &CmdArgs, const ArgList &Args) {
1829
3.56k
  ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
1830
  // By default OHOS binaries are linked statically to libunwind.
1831
3.56k
  if (TC.getTriple().isOHOSFamily() && 
UNW == ToolChain::UNW_CompilerRT67
) {
1832
67
    CmdArgs.push_back("-l:libunwind.a");
1833
67
    return;
1834
67
  }
1835
1836
  // Targets that don't use unwind libraries.
1837
3.49k
  if ((TC.getTriple().isAndroid() && 
UNW == ToolChain::UNW_Libgcc276
) ||
1838
3.49k
      TC.getTriple().isOSIAMCU() || 
TC.getTriple().isOSBinFormatWasm()3.48k
||
1839
3.49k
      
TC.getTriple().isWindowsMSVCEnvironment()3.43k
||
UNW == ToolChain::UNW_None3.42k
)
1840
361
    return;
1841
1842
3.13k
  LibGccType LGT = getLibGccType(TC, D, Args);
1843
3.13k
  bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
1844
3.13k
                  
(2.82k
UNW == ToolChain::UNW_CompilerRT2.82k
||
!D.CCCIsCXX()2.68k
) &&
1845
3.13k
                  
!TC.getTriple().isAndroid()2.74k
&&
1846
3.13k
                  
!TC.getTriple().isOSCygMing()2.74k
&&
!TC.getTriple().isOSAIX()2.74k
;
1847
3.13k
  if (AsNeeded)
1848
2.62k
    addAsNeededOption(TC, Args, CmdArgs, true);
1849
1850
3.13k
  switch (UNW) {
1851
0
  case ToolChain::UNW_None:
1852
0
    return;
1853
2.71k
  case ToolChain::UNW_Libgcc: {
1854
2.71k
    if (LGT == LibGccType::StaticLibGcc)
1855
24
      CmdArgs.push_back("-lgcc_eh");
1856
2.69k
    else
1857
2.69k
      CmdArgs.push_back("-lgcc_s");
1858
2.71k
    break;
1859
0
  }
1860
422
  case ToolChain::UNW_CompilerRT:
1861
422
    if (TC.getTriple().isOSAIX()) {
1862
      // AIX only has libunwind as a shared library. So do not pass
1863
      // anything in if -static is specified.
1864
122
      if (LGT != LibGccType::StaticLibGcc)
1865
119
        CmdArgs.push_back("-lunwind");
1866
300
    } else if (LGT == LibGccType::StaticLibGcc) {
1867
280
      CmdArgs.push_back("-l:libunwind.a");
1868
280
    } else 
if (20
LGT == LibGccType::SharedLibGcc20
) {
1869
4
      if (TC.getTriple().isOSCygMing())
1870
2
        CmdArgs.push_back("-l:libunwind.dll.a");
1871
2
      else
1872
2
        CmdArgs.push_back("-l:libunwind.so");
1873
16
    } else {
1874
      // Let the linker choose between libunwind.so and libunwind.a
1875
      // depending on what's available, and depending on the -static flag
1876
16
      CmdArgs.push_back("-lunwind");
1877
16
    }
1878
422
    break;
1879
3.13k
  }
1880
1881
3.13k
  if (AsNeeded)
1882
2.62k
    addAsNeededOption(TC, Args, CmdArgs, false);
1883
3.13k
}
1884
1885
static void AddLibgcc(const ToolChain &TC, const Driver &D,
1886
2.92k
                      ArgStringList &CmdArgs, const ArgList &Args) {
1887
2.92k
  LibGccType LGT = getLibGccType(TC, D, Args);
1888
2.92k
  if (LGT == LibGccType::StaticLibGcc ||
1889
2.92k
      
(2.88k
LGT == LibGccType::UnspecifiedLibGcc2.88k
&&
!D.CCCIsCXX()2.88k
))
1890
2.83k
    CmdArgs.push_back("-lgcc");
1891
2.92k
  AddUnwindLibrary(TC, D, CmdArgs, Args);
1892
2.92k
  if (LGT == LibGccType::SharedLibGcc ||
1893
2.92k
      
(2.91k
LGT == LibGccType::UnspecifiedLibGcc2.91k
&&
D.CCCIsCXX()2.88k
))
1894
86
    CmdArgs.push_back("-lgcc");
1895
2.92k
}
1896
1897
void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
1898
3.99k
                           ArgStringList &CmdArgs, const ArgList &Args) {
1899
  // Make use of compiler-rt if --rtlib option is used
1900
3.99k
  ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
1901
1902
3.99k
  switch (RLT) {
1903
642
  case ToolChain::RLT_CompilerRT:
1904
642
    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
1905
642
    AddUnwindLibrary(TC, D, CmdArgs, Args);
1906
642
    break;
1907
3.35k
  case ToolChain::RLT_Libgcc:
1908
    // Make sure libgcc is not used under MSVC environment by default
1909
3.35k
    if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1910
      // Issue error diagnostic if libgcc is explicitly specified
1911
      // through command line as --rtlib option argument.
1912
429
      Arg *A = Args.getLastArg(options::OPT_rtlib_EQ);
1913
429
      if (A && 
A->getValue() != StringRef("platform")6
) {
1914
1
        TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
1915
1
            << A->getValue() << "MSVC";
1916
1
      }
1917
429
    } else
1918
2.92k
      AddLibgcc(TC, D, CmdArgs, Args);
1919
3.35k
    break;
1920
3.99k
  }
1921
1922
  // On Android, the unwinder uses dl_iterate_phdr (or one of
1923
  // dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
1924
  // statically-linked executables, these functions come from libc.a instead.
1925
3.99k
  if (TC.getTriple().isAndroid() && 
!Args.hasArg(options::OPT_static)276
&&
1926
3.99k
      
!Args.hasArg(options::OPT_static_pie)268
)
1927
268
    CmdArgs.push_back("-ldl");
1928
3.99k
}
1929
1930
SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
1931
                                         const InputInfo &Output,
1932
                                         const InputInfo &Input,
1933
51.7k
                                         const Driver &D) {
1934
51.7k
  const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ);
1935
51.7k
  if (!A && 
!D.CCPrintInternalStats51.7k
)
1936
51.7k
    return {};
1937
1938
18
  SmallString<128> StatsFile;
1939
18
  if (A) {
1940
11
    StringRef SaveStats = A->getValue();
1941
11
    if (SaveStats == "obj" && 
Output.isFilename()4
) {
1942
4
      StatsFile.assign(Output.getFilename());
1943
4
      llvm::sys::path::remove_filename(StatsFile);
1944
7
    } else if (SaveStats != "cwd") {
1945
1
      D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
1946
1
      return {};
1947
1
    }
1948
1949
10
    StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
1950
10
    llvm::sys::path::append(StatsFile, BaseName);
1951
10
    llvm::sys::path::replace_extension(StatsFile, "stats");
1952
10
  } else {
1953
7
    assert(D.CCPrintInternalStats);
1954
7
    StatsFile.assign(D.CCPrintInternalStatReportFilename.empty()
1955
7
                         ? 
"-"2
1956
7
                         : 
D.CCPrintInternalStatReportFilename5
);
1957
7
  }
1958
17
  return StatsFile;
1959
18
}
1960
1961
void tools::addMultilibFlag(bool Enabled, const StringRef Flag,
1962
13.5k
                            Multilib::flags_list &Flags) {
1963
13.5k
  assert(Flag.front() == '-');
1964
13.5k
  if (Enabled) {
1965
6.58k
    Flags.push_back(Flag.str());
1966
6.99k
  } else {
1967
6.99k
    Flags.push_back(("!" + Flag.substr(1)).str());
1968
6.99k
  }
1969
13.5k
}
1970
1971
void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,
1972
                                  ArgStringList &CmdArgs, bool IsLTO,
1973
41.0k
                                  const StringRef PluginOptPrefix) {
1974
41.0k
  auto addArg = [&, IsLTO](const Twine &Arg) {
1975
25
    if (IsLTO) {
1976
4
      assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
1977
4
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
1978
21
    } else {
1979
21
      CmdArgs.push_back("-mllvm");
1980
21
      CmdArgs.push_back(Args.MakeArgString(Arg));
1981
21
    }
1982
25
  };
1983
1984
41.0k
  if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) {
1985
5
    addArg(Twine("-x86-branches-within-32B-boundaries"));
1986
5
  }
1987
41.0k
  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) {
1988
6
    StringRef Value = A->getValue();
1989
6
    unsigned Boundary;
1990
6
    if (Value.getAsInteger(10, Boundary) || Boundary < 16 ||
1991
6
        
!llvm::isPowerOf2_64(Boundary)4
) {
1992
2
      D.Diag(diag::err_drv_invalid_argument_to_option)
1993
2
          << Value << A->getOption().getName();
1994
4
    } else {
1995
4
      addArg("-x86-align-branch-boundary=" + Twine(Boundary));
1996
4
    }
1997
6
  }
1998
41.0k
  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) {
1999
11
    std::string AlignBranch;
2000
39
    for (StringRef T : A->getValues()) {
2001
39
      if (T != "fused" && 
T != "jcc"28
&&
T != "jmp"19
&&
T != "call"10
&&
2002
39
          
T != "ret"8
&&
T != "indirect"6
)
2003
4
        D.Diag(diag::err_drv_invalid_malign_branch_EQ)
2004
4
            << T << "fused, jcc, jmp, call, ret, indirect";
2005
39
      if (!AlignBranch.empty())
2006
28
        AlignBranch += '+';
2007
39
      AlignBranch += T;
2008
39
    }
2009
11
    addArg("-x86-align-branch=" + Twine(AlignBranch));
2010
11
  }
2011
41.0k
  if (const Arg *A = Args.getLastArg(options::OPT_mpad_max_prefix_size_EQ)) {
2012
5
    StringRef Value = A->getValue();
2013
5
    unsigned PrefixSize;
2014
5
    if (Value.getAsInteger(10, PrefixSize)) {
2015
0
      D.Diag(diag::err_drv_invalid_argument_to_option)
2016
0
          << Value << A->getOption().getName();
2017
5
    } else {
2018
5
      addArg("-x86-pad-max-prefix-size=" + Twine(PrefixSize));
2019
5
    }
2020
5
  }
2021
41.0k
}
2022
2023
/// SDLSearch: Search for Static Device Library
2024
/// The search for SDL bitcode files is consistent with how static host
2025
/// libraries are discovered. That is, the -l option triggers a search for
2026
/// files in a set of directories called the LINKPATH. The host library search
2027
/// procedure looks for a specific filename in the LINKPATH.  The filename for
2028
/// a host library is lib<libname>.a or lib<libname>.so. For SDLs, there is an
2029
/// ordered-set of filenames that are searched. We call this ordered-set of
2030
/// filenames as SEARCH-ORDER. Since an SDL can either be device-type specific,
2031
/// architecture specific, or generic across all architectures, a naming
2032
/// convention and search order is used where the file name embeds the
2033
/// architecture name <arch-name> (nvptx or amdgcn) and the GPU device type
2034
/// <device-name> such as sm_30 and gfx906. <device-name> is absent in case of
2035
/// device-independent SDLs. To reduce congestion in host library directories,
2036
/// the search first looks for files in the “libdevice” subdirectory. SDLs that
2037
/// are bc files begin with the prefix “lib”.
2038
///
2039
/// Machine-code SDLs can also be managed as an archive (*.a file). The
2040
/// convention has been to use the prefix “lib”. To avoid confusion with host
2041
/// archive libraries, we use prefix "libbc-" for the bitcode SDL archives.
2042
///
2043
bool tools::SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs,
2044
                      llvm::opt::ArgStringList &CC1Args,
2045
                      SmallVector<std::string, 8> LibraryPaths, std::string Lib,
2046
25
                      StringRef Arch, StringRef Target, bool isBitCodeSDL) {
2047
25
  SmallVector<std::string, 12> SDLs;
2048
2049
25
  std::string LibDeviceLoc = "/libdevice";
2050
25
  std::string LibBcPrefix = "/libbc-";
2051
25
  std::string LibPrefix = "/lib";
2052
2053
25
  if (isBitCodeSDL) {
2054
    // SEARCH-ORDER for Bitcode SDLs:
2055
    //       libdevice/libbc-<libname>-<arch-name>-<device-type>.a
2056
    //       libbc-<libname>-<arch-name>-<device-type>.a
2057
    //       libdevice/libbc-<libname>-<arch-name>.a
2058
    //       libbc-<libname>-<arch-name>.a
2059
    //       libdevice/libbc-<libname>.a
2060
    //       libbc-<libname>.a
2061
    //       libdevice/lib<libname>-<arch-name>-<device-type>.bc
2062
    //       lib<libname>-<arch-name>-<device-type>.bc
2063
    //       libdevice/lib<libname>-<arch-name>.bc
2064
    //       lib<libname>-<arch-name>.bc
2065
    //       libdevice/lib<libname>.bc
2066
    //       lib<libname>.bc
2067
2068
50
    for (StringRef Base : {LibBcPrefix, LibPrefix}) {
2069
50
      const auto *Ext = Base.contains(LibBcPrefix) ? 
".a"25
:
".bc"25
;
2070
2071
50
      for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
2072
150
                          Twine(Lib + "-" + Arch).str(), Twine(Lib).str()}) {
2073
150
        SDLs.push_back(Twine(LibDeviceLoc + Base + Suffix + Ext).str());
2074
150
        SDLs.push_back(Twine(Base + Suffix + Ext).str());
2075
150
      }
2076
50
    }
2077
25
  } else {
2078
    // SEARCH-ORDER for Machine-code SDLs:
2079
    //    libdevice/lib<libname>-<arch-name>-<device-type>.a
2080
    //    lib<libname>-<arch-name>-<device-type>.a
2081
    //    libdevice/lib<libname>-<arch-name>.a
2082
    //    lib<libname>-<arch-name>.a
2083
2084
0
    const auto *Ext = ".a";
2085
2086
0
    for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
2087
0
                        Twine(Lib + "-" + Arch).str()}) {
2088
0
      SDLs.push_back(Twine(LibDeviceLoc + LibPrefix + Suffix + Ext).str());
2089
0
      SDLs.push_back(Twine(LibPrefix + Suffix + Ext).str());
2090
0
    }
2091
0
  }
2092
2093
  // The CUDA toolchain does not use a global device llvm-link before the LLVM
2094
  // backend generates ptx. So currently, the use of bitcode SDL for nvptx is
2095
  // only possible with post-clang-cc1 linking. Clang cc1 has a feature that
2096
  // will link libraries after clang compilation while the LLVM IR is still in
2097
  // memory. This utilizes a clang cc1 option called “-mlink-builtin-bitcode”.
2098
  // This is a clang -cc1 option that is generated by the clang driver. The
2099
  // option value must a full path to an existing file.
2100
25
  bool FoundSDL = false;
2101
40
  for (auto LPath : LibraryPaths) {
2102
480
    for (auto SDL : SDLs) {
2103
480
      auto FullName = Twine(LPath + SDL).str();
2104
480
      if (llvm::sys::fs::exists(FullName)) {
2105
0
        CC1Args.push_back(DriverArgs.MakeArgString(FullName));
2106
0
        FoundSDL = true;
2107
0
        break;
2108
0
      }
2109
480
    }
2110
40
    if (FoundSDL)
2111
0
      break;
2112
40
  }
2113
25
  return FoundSDL;
2114
25
}
2115
2116
/// Search if a user provided archive file lib<libname>.a exists in any of
2117
/// the library paths. If so, add a new command to clang-offload-bundler to
2118
/// unbundle this archive and create a temporary device specific archive. Name
2119
/// of this SDL is passed to the llvm-link tool.
2120
bool tools::GetSDLFromOffloadArchive(
2121
    Compilation &C, const Driver &D, const Tool &T, const JobAction &JA,
2122
    const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs,
2123
    llvm::opt::ArgStringList &CC1Args, SmallVector<std::string, 8> LibraryPaths,
2124
25
    StringRef Lib, StringRef Arch, StringRef Target, bool isBitCodeSDL) {
2125
2126
  // We don't support bitcode archive bundles for nvptx
2127
25
  if (isBitCodeSDL && Arch.contains("nvptx"))
2128
0
    return false;
2129
2130
25
  bool FoundAOB = false;
2131
25
  std::string ArchiveOfBundles;
2132
2133
25
  llvm::Triple Triple(D.getTargetTriple());
2134
25
  bool IsMSVC = Triple.isWindowsMSVCEnvironment();
2135
25
  auto Ext = IsMSVC ? 
".lib"6
:
".a"19
;
2136
25
  if (!Lib.startswith(":") && !Lib.startswith("-l")) {
2137
10
    if (llvm::sys::fs::exists(Lib)) {
2138
6
      ArchiveOfBundles = Lib;
2139
6
      FoundAOB = true;
2140
6
    }
2141
15
  } else {
2142
15
    if (Lib.startswith("-l"))
2143
15
      Lib = Lib.drop_front(2);
2144
15
    for (auto LPath : LibraryPaths) {
2145
15
      ArchiveOfBundles.clear();
2146
15
      SmallVector<std::string, 2> AOBFileNames;
2147
15
      auto LibFile =
2148
15
          (Lib.startswith(":") ? 
Lib.drop_front()6
2149
15
                               : 
IsMSVC9
?
Lib + Ext2
:
"lib" + Lib + Ext7
)
2150
15
              .str();
2151
30
      for (auto Prefix : {"/libdevice/", "/"}) {
2152
30
        auto AOB = Twine(LPath + Prefix + LibFile).str();
2153
30
        if (llvm::sys::fs::exists(AOB)) {
2154
13
          ArchiveOfBundles = AOB;
2155
13
          FoundAOB = true;
2156
13
          break;
2157
13
        }
2158
30
      }
2159
15
      if (FoundAOB)
2160
13
        break;
2161
15
    }
2162
15
  }
2163
2164
25
  if (!FoundAOB)
2165
6
    return false;
2166
2167
19
  llvm::file_magic Magic;
2168
19
  auto EC = llvm::identify_magic(ArchiveOfBundles, Magic);
2169
19
  if (EC || Magic != llvm::file_magic::archive)
2170
4
    return false;
2171
2172
15
  StringRef Prefix = isBitCodeSDL ? "libbc-" : 
"lib"0
;
2173
15
  std::string OutputLib =
2174
15
      D.GetTemporaryPath(Twine(Prefix + llvm::sys::path::filename(Lib) + "-" +
2175
15
                               Arch + "-" + Target)
2176
15
                             .str(),
2177
15
                         "a");
2178
2179
15
  C.addTempFile(C.getArgs().MakeArgString(OutputLib));
2180
2181
15
  ArgStringList CmdArgs;
2182
15
  SmallString<128> DeviceTriple;
2183
15
  DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind());
2184
15
  DeviceTriple += '-';
2185
15
  std::string NormalizedTriple = T.getToolChain().getTriple().normalize();
2186
15
  DeviceTriple += NormalizedTriple;
2187
15
  if (!Target.empty()) {
2188
15
    DeviceTriple += '-';
2189
15
    DeviceTriple += Target;
2190
15
  }
2191
2192
15
  std::string UnbundleArg("-unbundle");
2193
15
  std::string TypeArg("-type=a");
2194
15
  std::string InputArg("-input=" + ArchiveOfBundles);
2195
15
  std::string OffloadArg("-targets=" + std::string(DeviceTriple));
2196
15
  std::string OutputArg("-output=" + OutputLib);
2197
2198
15
  const char *UBProgram = DriverArgs.MakeArgString(
2199
15
      T.getToolChain().GetProgramPath("clang-offload-bundler"));
2200
2201
15
  ArgStringList UBArgs;
2202
15
  UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg));
2203
15
  UBArgs.push_back(C.getArgs().MakeArgString(TypeArg));
2204
15
  UBArgs.push_back(C.getArgs().MakeArgString(InputArg));
2205
15
  UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg));
2206
15
  UBArgs.push_back(C.getArgs().MakeArgString(OutputArg));
2207
2208
  // Add this flag to not exit from clang-offload-bundler if no compatible
2209
  // code object is found in heterogenous archive library.
2210
15
  std::string AdditionalArgs("-allow-missing-bundles");
2211
15
  UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs));
2212
2213
  // Add this flag to treat hip and hipv4 offload kinds as compatible with
2214
  // openmp offload kind while extracting code objects from a heterogenous
2215
  // archive library. Vice versa is also considered compatible.
2216
15
  std::string HipCompatibleArgs("-hip-openmp-compatible");
2217
15
  UBArgs.push_back(C.getArgs().MakeArgString(HipCompatibleArgs));
2218
2219
15
  C.addCommand(std::make_unique<Command>(
2220
15
      JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs,
2221
15
      InputInfo(&JA, C.getArgs().MakeArgString(OutputLib))));
2222
2223
15
  CC1Args.push_back(DriverArgs.MakeArgString(OutputLib));
2224
2225
15
  return true;
2226
19
}
2227
2228
// Wrapper function used by driver for adding SDLs during link phase.
2229
void tools::AddStaticDeviceLibsLinking(Compilation &C, const Tool &T,
2230
                                       const JobAction &JA,
2231
                                       const InputInfoList &Inputs,
2232
                                       const llvm::opt::ArgList &DriverArgs,
2233
                                       llvm::opt::ArgStringList &CC1Args,
2234
                                       StringRef Arch, StringRef Target,
2235
297
                                       bool isBitCodeSDL) {
2236
297
  AddStaticDeviceLibs(&C, &T, &JA, &Inputs, C.getDriver(), DriverArgs, CC1Args,
2237
297
                      Arch, Target, isBitCodeSDL);
2238
297
}
2239
2240
// User defined Static Device Libraries(SDLs) can be passed to clang for
2241
// offloading GPU compilers. Like static host libraries, the use of a SDL is
2242
// specified with the -l command line option. The primary difference between
2243
// host and SDLs is the filenames for SDLs (refer SEARCH-ORDER for Bitcode SDLs
2244
// and SEARCH-ORDER for Machine-code SDLs for the naming convention).
2245
// SDLs are of following types:
2246
//
2247
// * Bitcode SDLs: They can either be a *.bc file or an archive of *.bc files.
2248
//           For NVPTX, these libraries are post-clang linked following each
2249
//           compilation. For AMDGPU, these libraries are linked one time
2250
//           during the application link phase.
2251
//
2252
// * Machine-code SDLs: They are archive files. For AMDGPU, the process for
2253
//           machine code SDLs is still in development. But they will be linked
2254
//           by the LLVM tool lld.
2255
//
2256
// * Bundled objects that contain both host and device codes: Bundled objects
2257
//           may also contain library code compiled from source. For NVPTX, the
2258
//           bundle contains cubin. For AMDGPU, the bundle contains bitcode.
2259
//
2260
// For Bitcode and Machine-code SDLs, current compiler toolchains hardcode the
2261
// inclusion of specific SDLs such as math libraries and the OpenMP device
2262
// library libomptarget.
2263
void tools::AddStaticDeviceLibs(Compilation *C, const Tool *T,
2264
                                const JobAction *JA,
2265
                                const InputInfoList *Inputs, const Driver &D,
2266
                                const llvm::opt::ArgList &DriverArgs,
2267
                                llvm::opt::ArgStringList &CC1Args,
2268
                                StringRef Arch, StringRef Target,
2269
297
                                bool isBitCodeSDL) {
2270
2271
297
  SmallVector<std::string, 8> LibraryPaths;
2272
  // Add search directories from LIBRARY_PATH env variable
2273
297
  std::optional<std::string> LibPath =
2274
297
      llvm::sys::Process::GetEnv("LIBRARY_PATH");
2275
297
  if (LibPath) {
2276
0
    SmallVector<StringRef, 8> Frags;
2277
0
    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
2278
0
    llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
2279
0
    for (StringRef Path : Frags)
2280
0
      LibraryPaths.emplace_back(Path.trim());
2281
0
  }
2282
2283
  // Add directories from user-specified -L options
2284
297
  for (std::string Search_Dir : DriverArgs.getAllArgValues(options::OPT_L))
2285
15
    LibraryPaths.emplace_back(Search_Dir);
2286
2287
  // Add path to lib-debug folders
2288
297
  SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
2289
297
  llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
2290
297
  LibraryPaths.emplace_back(DefaultLibPath.c_str());
2291
2292
  // Build list of Static Device Libraries SDLs specified by -l option
2293
297
  llvm::SmallSet<std::string, 16> SDLNames;
2294
297
  static const StringRef HostOnlyArchives[] = {
2295
297
      "omp", "cudart", "m", "gcc", "gcc_s", "pthread", "hip_hcc"};
2296
297
  for (auto SDLName : DriverArgs.getAllArgValues(options::OPT_l)) {
2297
15
    if (!HostOnlyArchives->contains(SDLName)) {
2298
15
      SDLNames.insert(std::string("-l") + SDLName);
2299
15
    }
2300
15
  }
2301
2302
383
  for (auto Input : DriverArgs.getAllArgValues(options::OPT_INPUT)) {
2303
383
    auto FileName = StringRef(Input);
2304
    // Clang treats any unknown file types as archives and passes them to the
2305
    // linker. Files with extension 'lib' are classified as TY_Object by clang
2306
    // but they are usually archives. It is OK if the file is not really an
2307
    // archive since GetSDLFromOffloadArchive will check the magic of the file
2308
    // and only unbundle it if it is really an archive.
2309
383
    const StringRef LibFileExt = ".lib";
2310
383
    if (!llvm::sys::path::has_extension(FileName) ||
2311
383
        types::lookupTypeForExtension(
2312
383
            llvm::sys::path::extension(FileName).drop_front()) ==
2313
383
            types::TY_INVALID ||
2314
383
        
llvm::sys::path::extension(FileName) == LibFileExt375
)
2315
10
      SDLNames.insert(Input);
2316
383
  }
2317
2318
  // The search stops as soon as an SDL file is found. The driver then provides
2319
  // the full filename of the SDL to the llvm-link command. If no SDL is found
2320
  // after searching each LINKPATH with SEARCH-ORDER, it is possible that an
2321
  // archive file lib<libname>.a exists and may contain bundled object files.
2322
297
  for (auto SDLName : SDLNames) {
2323
    // This is the only call to SDLSearch
2324
25
    if (!SDLSearch(D, DriverArgs, CC1Args, LibraryPaths, SDLName, Arch, Target,
2325
25
                   isBitCodeSDL)) {
2326
25
      GetSDLFromOffloadArchive(*C, D, *T, *JA, *Inputs, DriverArgs, CC1Args,
2327
25
                               LibraryPaths, SDLName, Arch, Target,
2328
25
                               isBitCodeSDL);
2329
25
    }
2330
25
  }
2331
297
}
2332
2333
static llvm::opt::Arg *
2334
1.61k
getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args) {
2335
1.61k
  return Args.getLastArg(options::OPT_mcode_object_version_EQ);
2336
1.61k
}
2337
2338
void tools::checkAMDGPUCodeObjectVersion(const Driver &D,
2339
510
                                         const llvm::opt::ArgList &Args) {
2340
510
  const unsigned MinCodeObjVer = 3;
2341
510
  const unsigned MaxCodeObjVer = 5;
2342
2343
510
  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
2344
13
    if (CodeObjArg->getOption().getID() ==
2345
13
        options::OPT_mcode_object_version_EQ) {
2346
13
      unsigned CodeObjVer = MaxCodeObjVer;
2347
13
      auto Remnant =
2348
13
          StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
2349
13
      if (Remnant || CodeObjVer < MinCodeObjVer || 
CodeObjVer > MaxCodeObjVer11
)
2350
2
        D.Diag(diag::err_drv_invalid_int_value)
2351
2
            << CodeObjArg->getAsString(Args) << CodeObjArg->getValue();
2352
13
    }
2353
13
  }
2354
510
}
2355
2356
unsigned tools::getAMDGPUCodeObjectVersion(const Driver &D,
2357
351
                                           const llvm::opt::ArgList &Args) {
2358
351
  unsigned CodeObjVer = 4; // default
2359
351
  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args))
2360
49
    StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
2361
351
  return CodeObjVer;
2362
351
}
2363
2364
bool tools::haveAMDGPUCodeObjectVersionArgument(
2365
755
    const Driver &D, const llvm::opt::ArgList &Args) {
2366
755
  return getAMDGPUCodeObjectArgument(D, Args) != nullptr;
2367
755
}
2368
2369
void tools::addMachineOutlinerArgs(const Driver &D,
2370
                                   const llvm::opt::ArgList &Args,
2371
                                   llvm::opt::ArgStringList &CmdArgs,
2372
                                   const llvm::Triple &Triple, bool IsLTO,
2373
48.3k
                                   const StringRef PluginOptPrefix) {
2374
48.3k
  auto addArg = [&, IsLTO](const Twine &Arg) {
2375
8
    if (IsLTO) {
2376
2
      assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
2377
2
      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
2378
6
    } else {
2379
6
      CmdArgs.push_back("-mllvm");
2380
6
      CmdArgs.push_back(Args.MakeArgString(Arg));
2381
6
    }
2382
8
  };
2383
2384
48.3k
  if (Arg *A = Args.getLastArg(options::OPT_moutline,
2385
48.3k
                               options::OPT_mno_outline)) {
2386
9
    if (A->getOption().matches(options::OPT_moutline)) {
2387
      // We only support -moutline in AArch64 and ARM targets right now. If
2388
      // we're not compiling for these, emit a warning and ignore the flag.
2389
      // Otherwise, add the proper mllvm flags.
2390
5
      if (!(Triple.isARM() || 
Triple.isThumb()2
||
2391
5
            
Triple.getArch() == llvm::Triple::aarch642
||
2392
5
            
Triple.getArch() == llvm::Triple::aarch64_321
)) {
2393
1
        D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
2394
4
      } else {
2395
4
        addArg(Twine("-enable-machine-outliner"));
2396
4
      }
2397
5
    } else {
2398
      // Disable all outlining behaviour.
2399
4
      addArg(Twine("-enable-machine-outliner=never"));
2400
4
    }
2401
9
  }
2402
48.3k
}
2403
2404
void tools::addOpenMPDeviceRTL(const Driver &D,
2405
                               const llvm::opt::ArgList &DriverArgs,
2406
                               llvm::opt::ArgStringList &CC1Args,
2407
                               StringRef BitcodeSuffix,
2408
0
                               const llvm::Triple &Triple) {
2409
0
  SmallVector<StringRef, 8> LibraryPaths;
2410
2411
  // Add path to clang lib / lib64 folder.
2412
0
  SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
2413
0
  llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
2414
0
  LibraryPaths.emplace_back(DefaultLibPath.c_str());
2415
2416
  // Add user defined library paths from LIBRARY_PATH.
2417
0
  std::optional<std::string> LibPath =
2418
0
      llvm::sys::Process::GetEnv("LIBRARY_PATH");
2419
0
  if (LibPath) {
2420
0
    SmallVector<StringRef, 8> Frags;
2421
0
    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
2422
0
    llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
2423
0
    for (StringRef Path : Frags)
2424
0
      LibraryPaths.emplace_back(Path.trim());
2425
0
  }
2426
2427
0
  OptSpecifier LibomptargetBCPathOpt =
2428
0
      Triple.isAMDGCN() ? options::OPT_libomptarget_amdgpu_bc_path_EQ
2429
0
                        : options::OPT_libomptarget_nvptx_bc_path_EQ;
2430
2431
0
  StringRef ArchPrefix = Triple.isAMDGCN() ? "amdgpu" : "nvptx";
2432
0
  std::string LibOmpTargetName =
2433
0
      ("libomptarget-" + ArchPrefix + "-" + BitcodeSuffix + ".bc").str();
2434
2435
  // First check whether user specifies bc library
2436
0
  if (const Arg *A = DriverArgs.getLastArg(LibomptargetBCPathOpt)) {
2437
0
    SmallString<128> LibOmpTargetFile(A->getValue());
2438
0
    if (llvm::sys::fs::exists(LibOmpTargetFile) &&
2439
0
        llvm::sys::fs::is_directory(LibOmpTargetFile)) {
2440
0
      llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2441
0
    }
2442
2443
0
    if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2444
0
      CC1Args.push_back("-mlink-builtin-bitcode");
2445
0
      CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2446
0
    } else {
2447
0
      D.Diag(diag::err_drv_omp_offload_target_bcruntime_not_found)
2448
0
          << LibOmpTargetFile;
2449
0
    }
2450
0
  } else {
2451
0
    bool FoundBCLibrary = false;
2452
2453
0
    for (StringRef LibraryPath : LibraryPaths) {
2454
0
      SmallString<128> LibOmpTargetFile(LibraryPath);
2455
0
      llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2456
0
      if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2457
0
        CC1Args.push_back("-mlink-builtin-bitcode");
2458
0
        CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2459
0
        FoundBCLibrary = true;
2460
0
        break;
2461
0
      }
2462
0
    }
2463
2464
0
    if (!FoundBCLibrary)
2465
0
      D.Diag(diag::err_drv_omp_offload_target_missingbcruntime)
2466
0
          << LibOmpTargetName << ArchPrefix;
2467
0
  }
2468
0
}
2469
void tools::addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C,
2470
                                 const llvm::opt::ArgList &Args,
2471
2.01k
                                 llvm::opt::ArgStringList &CmdArgs) {
2472
2.01k
  if ((C.getActiveOffloadKinds() & Action::OFK_HIP) &&
2473
2.01k
      
!Args.hasArg(options::OPT_nostdlib)162
&&
2474
2.01k
      
!Args.hasArg(options::OPT_no_hip_rt)160
) {
2475
159
    TC.AddHIPRuntimeLibArgs(Args, CmdArgs);
2476
1.85k
  } else {
2477
    // Claim "no HIP libraries" arguments if any
2478
1.85k
    for (auto *Arg : Args.filtered(options::OPT_no_hip_rt)) {
2479
1
      Arg->claim();
2480
1
    }
2481
1.85k
  }
2482
2.01k
}