diff options
Diffstat (limited to 'lib/Driver/ToolChains/Clang.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 246 |
1 files changed, 183 insertions, 63 deletions
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 75f16898df..91cc30520f 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -1,9 +1,8 @@ -//===--- LLVM.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===// +//===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -520,6 +519,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, case llvm::Triple::xcore: case llvm::Triple::wasm32: case llvm::Triple::wasm64: + case llvm::Triple::msp430: // XCore never wants frame pointers, regardless of OS. // WebAssembly never wants frame pointers. return false; @@ -534,6 +534,19 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, return !areOptimizationsEnabled(Args); } + if (Triple.isOSOpenBSD()) { + switch (Triple.getArch()) { + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::ppc: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return !areOptimizationsEnabled(Args); + default: + return true; + } + } + if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI || Triple.isOSHurd()) { switch (Triple.getArch()) { @@ -729,6 +742,13 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) PGOGenerateArg = nullptr; + auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate, + options::OPT_fcs_profile_generate_EQ, + options::OPT_fno_profile_generate); + if (CSPGOGenerateArg && + CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) + CSPGOGenerateArg = nullptr; + auto *ProfileGenerateArg = Args.getLastArg( options::OPT_fprofile_instr_generate, options::OPT_fprofile_instr_generate_EQ, @@ -752,6 +772,10 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, D.Diag(diag::err_drv_argument_not_allowed_with) << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling(); + if (CSPGOGenerateArg && PGOGenerateArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling(); + if (ProfileGenerateArg) { if (ProfileGenerateArg->getOption().matches( options::OPT_fprofile_instr_generate_EQ)) @@ -761,11 +785,22 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, CmdArgs.push_back("-fprofile-instrument=clang"); } + Arg *PGOGenArg = nullptr; if (PGOGenerateArg) { + assert(!CSPGOGenerateArg); + PGOGenArg = PGOGenerateArg; CmdArgs.push_back("-fprofile-instrument=llvm"); - if (PGOGenerateArg->getOption().matches( - options::OPT_fprofile_generate_EQ)) { - SmallString<128> Path(PGOGenerateArg->getValue()); + } + if (CSPGOGenerateArg) { + assert(!PGOGenerateArg); + PGOGenArg = CSPGOGenerateArg; + CmdArgs.push_back("-fprofile-instrument=csllvm"); + } + if (PGOGenArg) { + if (PGOGenArg->getOption().matches( + PGOGenerateArg ? options::OPT_fprofile_generate_EQ + : options::OPT_fcs_profile_generate_EQ)) { + SmallString<128> Path(PGOGenArg->getValue()); llvm::sys::path::append(Path, "default_%m.profraw"); CmdArgs.push_back( Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path)); @@ -1116,6 +1151,21 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, if (JA.isOffloading(Action::OFK_Cuda)) getToolChain().AddCudaIncludeArgs(Args, CmdArgs); + // If we are offloading to a target via OpenMP we need to include the + // openmp_wrappers folder which contains alternative system headers. + if (JA.isDeviceOffloading(Action::OFK_OpenMP) && + getToolChain().getTriple().isNVPTX()){ + if (!Args.hasArg(options::OPT_nobuiltininc)) { + // Add openmp_wrappers/* to our system include path. This lets us wrap + // standard library headers. + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + llvm::sys::path::append(P, "openmp_wrappers"); + CmdArgs.push_back("-internal-isystem"); + CmdArgs.push_back(Args.MakeArgString(P)); + } + } + // Add -i* options, and automatically translate to // -include-pch/-include-pth for transparent PCH support. It's // wonky, but we include looking for .gch so we can support seamless @@ -1716,6 +1766,14 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } else D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName; } + + if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls, + options::OPT_mno_relax_pic_calls)) { + if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mips-jalr-reloc=0"); + } + } } void Clang::AddPPCTargetArgs(const ArgList &Args, @@ -2023,6 +2081,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, bool TakeNextArg = false; bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations(); + bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault(); const char *MipsTargetFeature = nullptr; for (const Arg *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { @@ -2104,7 +2163,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } else if (Value == "--fatal-warnings") { CmdArgs.push_back("-massembler-fatal-warnings"); } else if (Value == "--noexecstack") { - CmdArgs.push_back("-mnoexecstack"); + UseNoExecStack = true; } else if (Value.startswith("-compress-debug-sections") || Value.startswith("--compress-debug-sections") || Value == "-nocompress-debug-sections" || @@ -2167,6 +2226,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } if (UseRelaxRelocations) CmdArgs.push_back("--mrelax-relocations"); + if (UseNoExecStack) + CmdArgs.push_back("-mnoexecstack"); if (MipsTargetFeature != nullptr) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back(MipsTargetFeature); @@ -2676,7 +2737,7 @@ static void RenderModulesOptions(Compilation &C, const Driver &D, } } - HaveModules = HaveClangModules; + HaveModules |= HaveClangModules; if (Args.hasArg(options::OPT_fmodules_ts)) { CmdArgs.push_back("-fmodules-ts"); HaveModules = true; @@ -3125,35 +3186,24 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, SplitDWARFInlining = false; } - if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { - if (checkDebugInfoOption(A, Args, D, TC)) { - // If the last option explicitly specified a debug-info level, use it. - if (A->getOption().matches(options::OPT_gN_Group)) { - DebugInfoKind = DebugLevelToInfoKind(*A); - // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses. - // But -gsplit-dwarf is not a g_group option, hence we have to check the - // order explicitly. If -gsplit-dwarf wins, we fix DebugInfoKind later. - // This gets a bit more complicated if you've disabled inline info in - // the skeleton CUs (SplitDWARFInlining) - then there's value in - // composing split-dwarf and line-tables-only, so let those compose - // naturally in that case. And if you just turned off debug info, - // (-gsplit-dwarf -g0) - do that. - if (DwarfFission != DwarfFissionKind::None) { - if (A->getIndex() > SplitDWARFArg->getIndex()) { - if (DebugInfoKind == codegenoptions::NoDebugInfo || - DebugInfoKind == codegenoptions::DebugDirectivesOnly || - (DebugInfoKind == codegenoptions::DebugLineTablesOnly && - SplitDWARFInlining)) - DwarfFission = DwarfFissionKind::None; - } else if (SplitDWARFInlining) - DebugInfoKind = codegenoptions::NoDebugInfo; - } - } else { - // For any other 'g' option, use Limited. - DebugInfoKind = codegenoptions::LimitedDebugInfo; - } - } else { - DebugInfoKind = codegenoptions::LimitedDebugInfo; + if (const Arg *A = + Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf, + options::OPT_gsplit_dwarf_EQ)) { + DebugInfoKind = codegenoptions::LimitedDebugInfo; + + // If the last option explicitly specified a debug-info level, use it. + if (checkDebugInfoOption(A, Args, D, TC) && + A->getOption().matches(options::OPT_gN_Group)) { + DebugInfoKind = DebugLevelToInfoKind(*A); + // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more + // complicated if you've disabled inline info in the skeleton CUs + // (SplitDWARFInlining) - then there's value in composing split-dwarf and + // line-tables-only, so let those compose naturally in that case. + if (DebugInfoKind == codegenoptions::NoDebugInfo || + DebugInfoKind == codegenoptions::DebugDirectivesOnly || + (DebugInfoKind == codegenoptions::DebugLineTablesOnly && + SplitDWARFInlining)) + DwarfFission = DwarfFissionKind::None; } } @@ -3228,17 +3278,12 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, } } - // -gsplit-dwarf should turn on -g and enable the backend dwarf - // splitting and extraction. - // FIXME: Currently only works on Linux and Fuchsia. - if (T.isOSLinux() || T.isOSFuchsia()) { + // -gsplit-dwarf enables the backend dwarf splitting and extraction. + if (T.isOSBinFormatELF()) { if (!SplitDWARFInlining) CmdArgs.push_back("-fno-split-dwarf-inlining"); if (DwarfFission != DwarfFissionKind::None) { - if (DebugInfoKind == codegenoptions::NoDebugInfo) - DebugInfoKind = codegenoptions::LimitedDebugInfo; - if (DwarfFission == DwarfFissionKind::Single) CmdArgs.push_back("-enable-split-dwarf=single"); else @@ -3251,9 +3296,10 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, // figure out if we need to "upgrade" it to standalone debug info. // We parse these two '-f' options whether or not they will be used, // to claim them even if you wrote "-fstandalone-debug -gline-tables-only" - bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug, - options::OPT_fno_standalone_debug, - TC.GetDefaultStandaloneDebug()); + bool NeedFullDebug = Args.hasFlag( + options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug, + DebuggerTuning == llvm::DebuggerKind::LLDB || + TC.GetDefaultStandaloneDebug()); if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug)) (void)checkDebugInfoOption(A, Args, D, TC); if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) @@ -3457,13 +3503,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>() ->getTriple() .normalize(); - else + else { + // Host-side compilation. NormalizedTriple = (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>() : C.getSingleOffloadToolChain<Action::OFK_HIP>()) ->getTriple() .normalize(); - + if (IsCuda) { + // We need to figure out which CUDA version we're compiling for, as that + // determines how we load and launch GPU kernels. + auto *CTC = static_cast<const toolchains::CudaToolChain *>( + C.getSingleOffloadToolChain<Action::OFK_Cuda>()); + assert(CTC && "Expected valid CUDA Toolchain."); + if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN) + CmdArgs.push_back(Args.MakeArgString( + Twine("-target-sdk-version=") + + CudaVersionToString(CTC->CudaInstallation.version()))); + } + } CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple)); } @@ -3638,9 +3696,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_mllvm, }; for (const auto &A : Args) - if (std::find(std::begin(kBitcodeOptionBlacklist), - std::end(kBitcodeOptionBlacklist), - A->getOption().getID()) != + if (llvm::find(kBitcodeOptionBlacklist, A->getOption().getID()) != std::end(kBitcodeOptionBlacklist)) D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling(); @@ -3790,6 +3846,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-pic-is-pie"); } + if (RelocationModel == llvm::Reloc::ROPI || + RelocationModel == llvm::Reloc::ROPI_RWPI) + CmdArgs.push_back("-fropi"); + if (RelocationModel == llvm::Reloc::RWPI || + RelocationModel == llvm::Reloc::ROPI_RWPI) + CmdArgs.push_back("-frwpi"); + if (Arg *A = Args.getLastArg(options::OPT_meabi)) { CmdArgs.push_back("-meabi"); CmdArgs.push_back(A->getValue()); @@ -4028,13 +4091,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Add the split debug info name to the command lines here so we // can propagate it to the backend. bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) && - (RawTriple.isOSLinux() || RawTriple.isOSFuchsia()) && + TC.getTriple().isOSBinFormatELF() && (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)); const char *SplitDWARFOut; if (SplitDWARF) { CmdArgs.push_back("-split-dwarf-file"); - SplitDWARFOut = SplitDebugName(Args, Output); + SplitDWARFOut = SplitDebugName(Args, Input, Output); CmdArgs.push_back(SplitDWARFOut); } @@ -4198,7 +4261,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // If a std is supplied, only add -trigraphs if it follows the // option. bool ImplyVCPPCXXVer = false; - if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { + const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi); + if (Std) { if (Std->getOption().matches(options::OPT_ansi)) if (types::isCXX(InputType)) CmdArgs.push_back("-std=c++98"); @@ -4437,6 +4501,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ); Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ); Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ); + Args.AddAllArgs(CmdArgs, + options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ); if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse, options::OPT_fno_openmp_optimistic_collapse, /*Default=*/false)) @@ -4495,7 +4561,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); + Args.AddLastArg(CmdArgs, options::OPT_ftime_trace); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); + Args.AddLastArg(CmdArgs, options::OPT_malign_double); if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { CmdArgs.push_back("-ftrapv-handler"); @@ -4584,6 +4652,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -f options with positive and negative forms; we translate // these by hand. if (Arg *A = getLastProfileSampleUseArg(Args)) { + auto *PGOArg = Args.getLastArg( + options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ, + options::OPT_fcs_profile_generate, options::OPT_fcs_profile_generate_EQ, + options::OPT_fprofile_use, options::OPT_fprofile_use_EQ); + if (PGOArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << "SampleUse with PGO options"; + StringRef fname = A->getValue(); if (!llvm::sys::fs::exists(fname)) D.Diag(diag::err_drv_no_such_file) << fname; @@ -4623,9 +4699,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes, options::OPT_fno_double_square_bracket_attributes); - bool HaveModules = false; - RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules); - // -faccess-control is default. if (Args.hasFlag(options::OPT_fno_access_control, options::OPT_faccess_control, false)) @@ -4692,6 +4765,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (ImplyVCPPCXXVer) { StringRef LanguageStandard; if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) { + Std = StdArg; LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue()) .Case("c++14", "-std=c++14") .Case("c++17", "-std=c++17") @@ -4757,6 +4831,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_inline_functions)) InlineArg->render(Args, CmdArgs); + // FIXME: Find a better way to determine whether the language has modules + // support by default, or just assume that all languages do. + bool HaveModules = + Std && (Std->containsValue("c++2a") || Std->containsValue("c++latest")); + RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules); + Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager); @@ -4973,8 +5053,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_apple_pragma_pack, false)) CmdArgs.push_back("-fapple-pragma-pack"); + // Remarks can be enabled with any of the `-f.*optimization-record.*` flags. if (Args.hasFlag(options::OPT_fsave_optimization_record, options::OPT_foptimization_record_file_EQ, + options::OPT_fno_save_optimization_record, false) || + Args.hasFlag(options::OPT_foptimization_record_passes_EQ, options::OPT_fno_save_optimization_record, false)) { CmdArgs.push_back("-opt-record-file"); @@ -5009,6 +5092,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, llvm::sys::path::replace_extension(F, "opt.yaml"); CmdArgs.push_back(Args.MakeArgString(F)); } + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { + CmdArgs.push_back("-opt-record-passes"); + CmdArgs.push_back(A->getValue()); + } } bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports, @@ -5058,6 +5146,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->claim(); } + // Forward -fpass-plugin=name.so to -cc1. + for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue())); + A->claim(); + } + // Setup statistics file output. SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D); if (!StatsFile.empty()) @@ -5271,6 +5366,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (Args.hasArg(options::OPT_forder_file_instrumentation)) { + CmdArgs.push_back("-forder-file-instrumentation"); + // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is + // on, we need to pass these flags as linker flags and that will be handled + // outside of the compiler. + if (!D.isUsingLTO()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-order-file-instrumentation"); + } + } + if (Arg *A = Args.getLastArg(options::OPT_fforce_enable_int128, options::OPT_fno_force_enable_int128)) { if (A->getOption().matches(options::OPT_fforce_enable_int128)) @@ -5845,6 +5951,15 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, } } +void ClangAs::AddRISCVTargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + const llvm::Triple &Triple = getToolChain().getTriple(); + StringRef ABIName = riscv::getRISCVABI(Args, Triple); + + CmdArgs.push_back("-target-abi"); + CmdArgs.push_back(ABIName.data()); +} + void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -6014,6 +6129,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-arm-add-build-attributes"); } break; + + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + AddRISCVTargetArgs(Args, CmdArgs); + break; } // Consume all the warning flags. Usually this would be handled more @@ -6034,10 +6154,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &T = getToolChain().getTriple(); Arg *A; - if ((getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split) && - (T.isOSLinux() || T.isOSFuchsia())) { + if (getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split && + T.isOSBinFormatELF()) { CmdArgs.push_back("-split-dwarf-file"); - CmdArgs.push_back(SplitDebugName(Args, Output)); + CmdArgs.push_back(SplitDebugName(Args, Input, Output)); } assert(Input.isFilename() && "Invalid input."); |