diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/Driver.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Driver.cpp | 527 |
1 files changed, 298 insertions, 229 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp index 180c412..1e0a48d 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Driver.cpp @@ -11,6 +11,7 @@ #include "InputInfo.h" #include "ToolChains.h" #include "clang/Basic/Version.h" +#include "clang/Basic/VirtualFileSystem.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" #include "clang/Driver/Compilation.h" @@ -46,9 +47,11 @@ using namespace clang; using namespace llvm::opt; Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, - DiagnosticsEngine &Diags) - : Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode), - SaveTemps(SaveTempsNone), ClangExecutable(ClangExecutable), + DiagnosticsEngine &Diags, + IntrusiveRefCntPtr<vfs::FileSystem> VFS) + : Opts(createDriverOptTable()), Diags(Diags), VFS(VFS), Mode(GCCMode), + SaveTemps(SaveTempsNone), LTOMode(LTOK_None), + ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple), DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr), @@ -57,8 +60,13 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true), CCCUsePCH(true), SuppressMissingInputWarning(false) { + // Provide a sane fallback if no VFS is specified. + if (!this->VFS) + this->VFS = vfs::getRealFileSystem(); + Name = llvm::sys::path::filename(ClangExecutable); Dir = llvm::sys::path::parent_path(ClangExecutable); + InstalledDir = Dir; // Provide a sensible default installed dir. // Compute the path to the resource directory. StringRef ClangResourceDir(CLANG_RESOURCE_DIR); @@ -174,10 +182,8 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) { FinalPhase = phases::Backend; - // -c and partial CUDA compilations only run up to the assembler. - } else if ((PhaseArg = DAL.getLastArg(options::OPT_c)) || - (PhaseArg = DAL.getLastArg(options::OPT_cuda_device_only)) || - (PhaseArg = DAL.getLastArg(options::OPT_cuda_host_only))) { + // -c compilation only runs up to the assembler. + } else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) { FinalPhase = phases::Assemble; // Otherwise do everything. @@ -203,6 +209,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { DerivedArgList *DAL = new DerivedArgList(Args); bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); + bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs); for (Arg *A : Args) { // Unfortunately, we have to parse some forwarding options (-Xassembler, // -Xlinker, -Xpreprocessor) because we either integrate their functionality @@ -217,7 +224,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle)); // Add the remaining values as Xlinker arguments. - for (const StringRef Val : A->getValues()) + for (StringRef Val : A->getValues()) if (Val != "--no-demangle") DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), Val); @@ -246,7 +253,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { StringRef Value = A->getValue(); // Rewrite unless -nostdlib is present. - if (!HasNostdlib && Value == "stdc++") { + if (!HasNostdlib && !HasNodefaultlib && Value == "stdc++") { DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx)); continue; } @@ -261,7 +268,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { // Pick up inputs via the -- option. if (A->getOption().matches(options::OPT__DASH_DASH)) { A->claim(); - for (const StringRef Val : A->getValues()) + for (StringRef Val : A->getValues()) DAL->append(MakeInputArg(*DAL, Opts, Val)); continue; } @@ -327,7 +334,8 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, } // Skip further flag support on OSes which don't support '-m32' or '-m64'. - if (Target.getArchName() == "tce" || Target.getOS() == llvm::Triple::Minix) + if (Target.getArch() == llvm::Triple::tce || + Target.getOS() == llvm::Triple::Minix) return Target; // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'. @@ -360,6 +368,32 @@ static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, return Target; } +// \brief Parse the LTO options and record the type of LTO compilation +// based on which -f(no-)?lto(=.*)? option occurs last. +void Driver::setLTOMode(const llvm::opt::ArgList &Args) { + LTOMode = LTOK_None; + if (!Args.hasFlag(options::OPT_flto, options::OPT_flto_EQ, + options::OPT_fno_lto, false)) + return; + + StringRef LTOName("full"); + + const Arg *A = Args.getLastArg(options::OPT_flto_EQ); + if (A) + LTOName = A->getValue(); + + LTOMode = llvm::StringSwitch<LTOKind>(LTOName) + .Case("full", LTOK_Full) + .Case("thin", LTOK_Thin) + .Default(LTOK_Unknown); + + if (LTOMode == LTOK_Unknown) { + assert(A); + Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() + << A->getValue(); + } +} + Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { llvm::PrettyStackTraceString CrashInfo("Compilation construction"); @@ -387,6 +421,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { InputArgList Args = ParseArgStrings(ArgList.slice(1)); + // Silence driver warnings if requested + Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w)); + // -no-canonical-prefixes is used very early in main. Args.ClaimAllArgs(options::OPT_no_canonical_prefixes); @@ -411,6 +448,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // clang-cl targets MSVC-style Win32. llvm::Triple T(DefaultTargetTriple); T.setOS(llvm::Triple::Win32); + T.setVendor(llvm::Triple::PC); T.setEnvironment(llvm::Triple::MSVC); DefaultTargetTriple = T.str(); } @@ -439,6 +477,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { .Default(SaveTempsCwd); } + setLTOMode(Args); + std::unique_ptr<llvm::opt::InputArgList> UArgs = llvm::make_unique<InputArgList>(std::move(Args)); @@ -452,6 +492,10 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // The compilation takes ownership of Args. Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs); + C->setCudaDeviceToolChain( + &getToolChain(C->getArgs(), llvm::Triple(TC.getTriple().isArch64Bit() + ? "nvptx64-nvidia-cuda" + : "nvptx-nvidia-cuda"))); if (!HandleImmediateArgs(*C)) return C; @@ -462,10 +506,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // Construct the list of abstract actions to perform for this compilation. On // MachO targets this uses the driver-driver and universal actions. if (TC.getTriple().isOSBinFormatMachO()) - BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(), Inputs, - C->getActions()); + BuildUniversalActions(*C, C->getDefaultToolChain(), Inputs); else - BuildActions(C->getDefaultToolChain(), C->getArgs(), Inputs, + BuildActions(*C, C->getDefaultToolChain(), C->getArgs(), Inputs, C->getActions()); if (CCCPrintPhases) { @@ -578,9 +621,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C, // Darwin OSes this uses the driver-driver and builds universal actions. const ToolChain &TC = C.getDefaultToolChain(); if (TC.getTriple().isOSBinFormatMachO()) - BuildUniversalActions(TC, C.getArgs(), Inputs, C.getActions()); + BuildUniversalActions(C, TC, Inputs); else - BuildActions(TC, C.getArgs(), Inputs, C.getActions()); + BuildActions(C, TC, C.getArgs(), Inputs, C.getActions()); BuildJobs(C); @@ -656,11 +699,11 @@ void Driver::generateCompilationDiagnostics(Compilation &C, } void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) { - // Since argumentsFitWithinSystemLimits() may underestimate system's capacity + // Since commandLineFitsWithinSystemLimits() may underestimate system's capacity // if the tool does not support response files, there is a chance/ that things // will just work without a response file, so we silently just skip it. if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None || - llvm::sys::argumentsFitWithinSystemLimits(Cmd.getArguments())) + llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), Cmd.getArguments())) return; std::string TmpName = GetTemporaryPath("response", "txt"); @@ -761,6 +804,9 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { } else OS << "Thread model: " << TC.getThreadModel(); OS << '\n'; + + // Print out the install directory. + OS << "InstalledDir: " << InstalledDir << '\n'; } /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories @@ -906,7 +952,7 @@ static unsigned PrintActions1(const Compilation &C, Action *A, os << '"' << CDA->getGpuArchName() << '"' << ", {" << PrintActions1(C, *CDA->begin(), Ids) << "}"; } else { - ActionList *AL; + const ActionList *AL; if (CudaHostAction *CHA = dyn_cast<CudaHostAction>(A)) { os << "{" << PrintActions1(C, *CHA->begin(), Ids) << "}" << ", gpu binaries "; @@ -914,12 +960,15 @@ static unsigned PrintActions1(const Compilation &C, Action *A, } else AL = &A->getInputs(); - const char *Prefix = "{"; - for (Action *PreRequisite : *AL) { - os << Prefix << PrintActions1(C, PreRequisite, Ids); - Prefix = ", "; - } - os << "}"; + if (AL->size()) { + const char *Prefix = "{"; + for (Action *PreRequisite : *AL) { + os << Prefix << PrintActions1(C, PreRequisite, Ids); + Prefix = ", "; + } + os << "}"; + } else + os << "{}"; } unsigned Id = Ids.size(); @@ -945,16 +994,17 @@ static bool ContainsCompileOrAssembleAction(const Action *A) { isa<AssembleJobAction>(A)) return true; - for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it) - if (ContainsCompileOrAssembleAction(*it)) + for (const Action *Input : *A) + if (ContainsCompileOrAssembleAction(Input)) return true; return false; } -void Driver::BuildUniversalActions(const ToolChain &TC, DerivedArgList &Args, - const InputList &BAInputs, - ActionList &Actions) const { +void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, + const InputList &BAInputs) const { + DerivedArgList &Args = C.getArgs(); + ActionList &Actions = C.getActions(); llvm::PrettyStackTraceString CrashInfo("Building universal build actions"); // Collect the list of architectures. Duplicates are allowed, but should only // be handled once (in the order seen). @@ -983,13 +1033,11 @@ void Driver::BuildUniversalActions(const ToolChain &TC, DerivedArgList &Args, Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName())); ActionList SingleActions; - BuildActions(TC, Args, BAInputs, SingleActions); + BuildActions(C, TC, Args, BAInputs, SingleActions); // Add in arch bindings for every top level action, as well as lipo and // dsymutil steps if needed. - for (unsigned i = 0, e = SingleActions.size(); i != e; ++i) { - Action *Act = SingleActions[i]; - + for (Action* Act : SingleActions) { // Make sure we can lipo this kind of output. If not (and it is an actual // output) then we disallow, since we can't create an output file with the // right name without overwriting it. We could remove this oddity by just @@ -1001,19 +1049,15 @@ void Driver::BuildUniversalActions(const ToolChain &TC, DerivedArgList &Args, << types::getTypeName(Act->getType()); ActionList Inputs; - for (unsigned i = 0, e = Archs.size(); i != e; ++i) { - Inputs.push_back( - new BindArchAction(std::unique_ptr<Action>(Act), Archs[i])); - if (i != 0) - Inputs.back()->setOwnsInputs(false); - } + for (unsigned i = 0, e = Archs.size(); i != e; ++i) + Inputs.push_back(C.MakeAction<BindArchAction>(Act, Archs[i])); // Lipo if necessary, we do it this way because we need to set the arch flag // so that -Xarch_ gets overwritten. if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing) Actions.append(Inputs.begin(), Inputs.end()); else - Actions.push_back(new LipoJobAction(Inputs, Act->getType())); + Actions.push_back(C.MakeAction<LipoJobAction>(Inputs, Act->getType())); // Handle debug info queries. Arg *A = Args.getLastArg(options::OPT_g_Group); @@ -1029,15 +1073,16 @@ void Driver::BuildUniversalActions(const ToolChain &TC, DerivedArgList &Args, ActionList Inputs; Inputs.push_back(Actions.back()); Actions.pop_back(); - Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM)); + Actions.push_back( + C.MakeAction<DsymutilJobAction>(Inputs, types::TY_dSYM)); } // Verify the debug info output. if (Args.hasArg(options::OPT_verify_debug_info)) { - std::unique_ptr<Action> VerifyInput(Actions.back()); + Action* LastAction = Actions.back(); Actions.pop_back(); - Actions.push_back(new VerifyDebugInfoJobAction(std::move(VerifyInput), - types::TY_Nothing)); + Actions.push_back(C.MakeAction<VerifyDebugInfoJobAction>( + LastAction, types::TY_Nothing)); } } } @@ -1228,28 +1273,36 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, } } -// For each unique --cuda-gpu-arch= argument creates a TY_CUDA_DEVICE input -// action and then wraps each in CudaDeviceAction paired with appropriate GPU -// arch name. If we're only building device-side code, each action remains -// independent. Otherwise we pass device-side actions as inputs to a new -// CudaHostAction which combines both host and device side actions. -static std::unique_ptr<Action> -buildCudaActions(const Driver &D, const ToolChain &TC, DerivedArgList &Args, - const Arg *InputArg, const types::ID InputType, - std::unique_ptr<Action> Current, ActionList &Actions) { - - assert(InputType == types::TY_CUDA && - "CUDA Actions only apply to CUDA inputs."); +// For each unique --cuda-gpu-arch= argument creates a TY_CUDA_DEVICE +// input action and then wraps each in CudaDeviceAction paired with +// appropriate GPU arch name. In case of partial (i.e preprocessing +// only) or device-only compilation, each device action is added to /p +// Actions and /p Current is released. Otherwise the function creates +// and returns a new CudaHostAction which wraps /p Current and device +// side actions. +static Action *buildCudaActions(Compilation &C, DerivedArgList &Args, + const Arg *InputArg, Action *HostAction, + ActionList &Actions) { + Arg *PartialCompilationArg = Args.getLastArg(options::OPT_cuda_host_only, + options::OPT_cuda_device_only); + // Host-only compilation case. + if (PartialCompilationArg && + PartialCompilationArg->getOption().matches(options::OPT_cuda_host_only)) + return C.MakeAction<CudaHostAction>(HostAction, ActionList()); // Collect all cuda_gpu_arch parameters, removing duplicates. SmallVector<const char *, 4> GpuArchList; llvm::StringSet<> GpuArchNames; for (Arg *A : Args) { - if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ)) { - A->claim(); - if (GpuArchNames.insert(A->getValue()).second) - GpuArchList.push_back(A->getValue()); - } + if (!A->getOption().matches(options::OPT_cuda_gpu_arch_EQ)) + continue; + A->claim(); + + const auto& Arch = A->getValue(); + if (!CudaDeviceAction::IsValidGpuArchName(Arch)) + C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << Arch; + else if (GpuArchNames.insert(Arch).second) + GpuArchList.push_back(Arch); } // Default to sm_20 which is the lowest common denominator for supported GPUs. @@ -1259,27 +1312,27 @@ buildCudaActions(const Driver &D, const ToolChain &TC, DerivedArgList &Args, // Replicate inputs for each GPU architecture. Driver::InputList CudaDeviceInputs; - for (unsigned i = 0, e = GpuArchList.size(); i != e; ++i) + for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) CudaDeviceInputs.push_back(std::make_pair(types::TY_CUDA_DEVICE, InputArg)); // Build actions for all device inputs. + assert(C.getCudaDeviceToolChain() && + "Missing toolchain for device-side compilation."); ActionList CudaDeviceActions; - D.BuildActions(TC, Args, CudaDeviceInputs, CudaDeviceActions); + C.getDriver().BuildActions(C, *C.getCudaDeviceToolChain(), Args, + CudaDeviceInputs, CudaDeviceActions); assert(GpuArchList.size() == CudaDeviceActions.size() && "Failed to create actions for all devices"); // Check whether any of device actions stopped before they could generate PTX. - bool PartialCompilation = false; - bool DeviceOnlyCompilation = Args.hasArg(options::OPT_cuda_device_only); - for (unsigned i = 0, e = GpuArchList.size(); i != e; ++i) { - if (CudaDeviceActions[i]->getKind() != Action::BackendJobClass) { - PartialCompilation = true; - break; - } - } + bool PartialCompilation = + llvm::any_of(CudaDeviceActions, [](const Action *a) { + return a->getKind() != Action::BackendJobClass; + }); // Figure out what to do with device actions -- pass them as inputs to the // host action or run each of them independently. + bool DeviceOnlyCompilation = PartialCompilationArg != nullptr; if (PartialCompilation || DeviceOnlyCompilation) { // In case of partial or device-only compilation results of device actions // are not consumed by the host action device actions have to be added to @@ -1288,35 +1341,36 @@ buildCudaActions(const Driver &D, const ToolChain &TC, DerivedArgList &Args, // -o is ambiguous if we have more than one top-level action. if (Args.hasArg(options::OPT_o) && (!DeviceOnlyCompilation || GpuArchList.size() > 1)) { - D.Diag(clang::diag::err_drv_output_argument_with_multiple_files); + C.getDriver().Diag( + clang::diag::err_drv_output_argument_with_multiple_files); return nullptr; } - for (unsigned i = 0, e = GpuArchList.size(); i != e; ++i) - Actions.push_back( - new CudaDeviceAction(std::unique_ptr<Action>(CudaDeviceActions[i]), - GpuArchList[i], /* AtTopLevel */ true)); + for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) + Actions.push_back(C.MakeAction<CudaDeviceAction>(CudaDeviceActions[I], + GpuArchList[I], + /* AtTopLevel */ true)); // Kill host action in case of device-only compilation. if (DeviceOnlyCompilation) - Current.reset(nullptr); - return Current; - } else { - // Outputs of device actions during complete CUDA compilation get created - // with AtTopLevel=false and become inputs for the host action. - ActionList DeviceActions; - for (unsigned i = 0, e = GpuArchList.size(); i != e; ++i) - DeviceActions.push_back( - new CudaDeviceAction(std::unique_ptr<Action>(CudaDeviceActions[i]), - GpuArchList[i], /* AtTopLevel */ false)); - // Return a new host action that incorporates original host action and all - // device actions. - return std::unique_ptr<Action>( - new CudaHostAction(std::move(Current), DeviceActions)); - } + return nullptr; + return HostAction; + } + + // Outputs of device actions during complete CUDA compilation get created + // with AtTopLevel=false and become inputs for the host action. + ActionList DeviceActions; + for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) + DeviceActions.push_back( + C.MakeAction<CudaDeviceAction>(CudaDeviceActions[I], GpuArchList[I], + /* AtTopLevel */ false)); + // Return a new host action that incorporates original host action and all + // device actions. + return C.MakeAction<CudaHostAction>(HostAction, DeviceActions); } -void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, - const InputList &Inputs, ActionList &Actions) const { +void Driver::BuildActions(Compilation &C, const ToolChain &TC, + DerivedArgList &Args, const InputList &Inputs, + ActionList &Actions) const { llvm::PrettyStackTraceString CrashInfo("Building compilation actions"); if (!SuppressMissingInputWarning && Inputs.empty()) { @@ -1373,9 +1427,9 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, ActionList LinkerInputs; llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL; - for (unsigned i = 0, e = Inputs.size(); i != e; ++i) { - types::ID InputType = Inputs[i].first; - const Arg *InputArg = Inputs[i].second; + for (auto &I : Inputs) { + types::ID InputType = I.first; + const Arg *InputArg = I.second; PL.clear(); types::getCompilationPhases(InputType, PL); @@ -1412,27 +1466,14 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, continue; } - phases::ID CudaInjectionPhase; - if (isSaveTempsEnabled()) { - // All phases are done independently, inject GPU blobs during compilation - // phase as that's where we generate glue code to init them. - CudaInjectionPhase = phases::Compile; - } else { - // Assumes that clang does everything up until linking phase, so we inject - // cuda device actions at the last step before linking. Otherwise CUDA - // host action forces preprocessor into a separate invocation. - if (FinalPhase == phases::Link) { - for (auto i = PL.begin(), e = PL.end(); i != e; ++i) { - auto next = i + 1; - if (next != e && *next == phases::Link) - CudaInjectionPhase = *i; - } - } else - CudaInjectionPhase = FinalPhase; - } + phases::ID CudaInjectionPhase = + (phases::Compile < FinalPhase && + llvm::find(PL, phases::Compile) != PL.end()) + ? phases::Compile + : FinalPhase; // Build the pipeline for this file. - std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType)); + Action *Current = C.MakeAction<InputAction>(*InputArg, InputType); for (SmallVectorImpl<phases::ID>::iterator i = PL.begin(), e = PL.end(); i != e; ++i) { phases::ID Phase = *i; @@ -1444,7 +1485,8 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, // Queue linker inputs. if (Phase == phases::Link) { assert((i + 1) == e && "linking must be final compilation step."); - LinkerInputs.push_back(Current.release()); + LinkerInputs.push_back(Current); + Current = nullptr; break; } @@ -1455,12 +1497,10 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, continue; // Otherwise construct the appropriate action. - Current = ConstructPhaseAction(TC, Args, Phase, std::move(Current)); + Current = ConstructPhaseAction(C, TC, Args, Phase, Current); - if (InputType == types::TY_CUDA && Phase == CudaInjectionPhase && - !Args.hasArg(options::OPT_cuda_host_only)) { - Current = buildCudaActions(*this, TC, Args, InputArg, InputType, - std::move(Current), Actions); + if (InputType == types::TY_CUDA && Phase == CudaInjectionPhase) { + Current = buildCudaActions(C, Args, InputArg, Current, Actions); if (!Current) break; } @@ -1471,12 +1511,13 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, // If we ended with something, add to the output list. if (Current) - Actions.push_back(Current.release()); + Actions.push_back(Current); } // Add a link action if necessary. if (!LinkerInputs.empty()) - Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image)); + Actions.push_back( + C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image)); // If we are linking, claim any options which are obviously only used for // compilation. @@ -1487,12 +1528,15 @@ void Driver::BuildActions(const ToolChain &TC, DerivedArgList &Args, // Claim ignored clang-cl options. Args.ClaimAllArgs(options::OPT_cl_ignored_Group); + + // Claim --cuda-host-only arg which may be passed to non-CUDA + // compilations and should not trigger warnings there. + Args.ClaimAllArgs(options::OPT_cuda_host_only); } -std::unique_ptr<Action> -Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, - phases::ID Phase, - std::unique_ptr<Action> Input) const { +Action *Driver::ConstructPhaseAction(Compilation &C, const ToolChain &TC, + const ArgList &Args, phases::ID Phase, + Action *Input) const { llvm::PrettyStackTraceString CrashInfo("Constructing phase actions"); // Build the appropriate action. switch (Phase) { @@ -1512,7 +1556,7 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, assert(OutputTy != types::TY_INVALID && "Cannot preprocess this input type!"); } - return llvm::make_unique<PreprocessJobAction>(std::move(Input), OutputTy); + return C.MakeAction<PreprocessJobAction>(Input, OutputTy); } case phases::Precompile: { types::ID OutputTy = types::TY_PCH; @@ -1520,62 +1564,48 @@ Driver::ConstructPhaseAction(const ToolChain &TC, const ArgList &Args, // Syntax checks should not emit a PCH file OutputTy = types::TY_Nothing; } - return llvm::make_unique<PrecompileJobAction>(std::move(Input), OutputTy); + return C.MakeAction<PrecompileJobAction>(Input, OutputTy); } case phases::Compile: { if (Args.hasArg(options::OPT_fsyntax_only)) - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_Nothing); + return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing); if (Args.hasArg(options::OPT_rewrite_objc)) - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_RewrittenObjC); + return C.MakeAction<CompileJobAction>(Input, types::TY_RewrittenObjC); if (Args.hasArg(options::OPT_rewrite_legacy_objc)) - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_RewrittenLegacyObjC); + return C.MakeAction<CompileJobAction>(Input, + types::TY_RewrittenLegacyObjC); if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto)) - return llvm::make_unique<AnalyzeJobAction>(std::move(Input), - types::TY_Plist); + return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist); if (Args.hasArg(options::OPT__migrate)) - return llvm::make_unique<MigrateJobAction>(std::move(Input), - types::TY_Remap); + return C.MakeAction<MigrateJobAction>(Input, types::TY_Remap); if (Args.hasArg(options::OPT_emit_ast)) - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_AST); + return C.MakeAction<CompileJobAction>(Input, types::TY_AST); if (Args.hasArg(options::OPT_module_file_info)) - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_ModuleFile); + return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) - return llvm::make_unique<VerifyPCHJobAction>(std::move(Input), - types::TY_Nothing); - return llvm::make_unique<CompileJobAction>(std::move(Input), - types::TY_LLVM_BC); + return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); + return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); } case phases::Backend: { - if (IsUsingLTO(Args)) { + if (isUsingLTO()) { types::ID Output = Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; - return llvm::make_unique<BackendJobAction>(std::move(Input), Output); + return C.MakeAction<BackendJobAction>(Input, Output); } if (Args.hasArg(options::OPT_emit_llvm)) { types::ID Output = Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC; - return llvm::make_unique<BackendJobAction>(std::move(Input), Output); + return C.MakeAction<BackendJobAction>(Input, Output); } - return llvm::make_unique<BackendJobAction>(std::move(Input), - types::TY_PP_Asm); + return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm); } case phases::Assemble: - return llvm::make_unique<AssembleJobAction>(std::move(Input), - types::TY_Object); + return C.MakeAction<AssembleJobAction>(Input, types::TY_Object); } llvm_unreachable("invalid phase in ConstructPhaseAction"); } -bool Driver::IsUsingLTO(const ArgList &Args) const { - return Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false); -} - void Driver::BuildJobs(Compilation &C) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); @@ -1617,12 +1647,11 @@ void Driver::BuildJobs(Compilation &C) const { LinkingOutput = getDefaultImageName(); } - InputInfo II; BuildJobsForAction(C, A, &C.getDefaultToolChain(), /*BoundArch*/ nullptr, /*AtTopLevel*/ true, /*MultipleArchs*/ ArchNames.size() > 1, - /*LinkingOutput*/ LinkingOutput, II); + /*LinkingOutput*/ LinkingOutput); } // If the user passed -Qunused-arguments or there were errors, don't warn @@ -1668,10 +1697,17 @@ void Driver::BuildJobs(Compilation &C) const { } } -static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, +// Returns a Tool for a given JobAction. In case the action and its +// predecessors can be combined, updates Inputs with the inputs of the +// first combined action. If one of the collapsed actions is a +// CudaHostAction, updates CollapsedCHA with the pointer to it so the +// caller can deal with extra handling such action requires. +static const Tool *selectToolForJob(Compilation &C, bool SaveTemps, const ToolChain *TC, const JobAction *JA, - const ActionList *&Inputs) { + const ActionList *&Inputs, + const CudaHostAction *&CollapsedCHA) { const Tool *ToolForJob = nullptr; + CollapsedCHA = nullptr; // See if we should look for a compiler with an integrated assembler. We match // bottom up, so what we are actually looking for is an assembler job with a @@ -1688,13 +1724,19 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, // checking the backend tool, check if the tool for the CompileJob // has an integrated assembler. const ActionList *BackendInputs = &(*Inputs)[0]->getInputs(); - JobAction *CompileJA = cast<CompileJobAction>(*BackendInputs->begin()); + // Compile job may be wrapped in CudaHostAction, extract it if + // that's the case and update CollapsedCHA if we combine phases. + CudaHostAction *CHA = dyn_cast<CudaHostAction>(*BackendInputs->begin()); + JobAction *CompileJA = + cast<CompileJobAction>(CHA ? *CHA->begin() : *BackendInputs->begin()); + assert(CompileJA && "Backend job is not preceeded by compile job."); const Tool *Compiler = TC->SelectTool(*CompileJA); if (!Compiler) return nullptr; if (Compiler->hasIntegratedAssembler()) { - Inputs = &(*BackendInputs)[0]->getInputs(); + Inputs = &CompileJA->getInputs(); ToolForJob = Compiler; + CollapsedCHA = CHA; } } @@ -1704,19 +1746,19 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, if (isa<BackendJobAction>(JA)) { // Check if the compiler supports emitting LLVM IR. assert(Inputs->size() == 1); - JobAction *CompileJA; - // Extract real host action, if it's a CudaHostAction. - if (CudaHostAction *CudaHA = dyn_cast<CudaHostAction>(*Inputs->begin())) - CompileJA = cast<CompileJobAction>(*CudaHA->begin()); - else - CompileJA = cast<CompileJobAction>(*Inputs->begin()); - + // Compile job may be wrapped in CudaHostAction, extract it if + // that's the case and update CollapsedCHA if we combine phases. + CudaHostAction *CHA = dyn_cast<CudaHostAction>(*Inputs->begin()); + JobAction *CompileJA = + cast<CompileJobAction>(CHA ? *CHA->begin() : *Inputs->begin()); + assert(CompileJA && "Backend job is not preceeded by compile job."); const Tool *Compiler = TC->SelectTool(*CompileJA); if (!Compiler) return nullptr; if (!Compiler->canEmitIR() || !SaveTemps) { - Inputs = &(*Inputs)[0]->getInputs(); + Inputs = &CompileJA->getInputs(); ToolForJob = Compiler; + CollapsedCHA = CHA; } } @@ -1737,21 +1779,19 @@ static const Tool *SelectToolForJob(Compilation &C, bool SaveTemps, return ToolForJob; } -void Driver::BuildJobsForAction(Compilation &C, const Action *A, - const ToolChain *TC, const char *BoundArch, - bool AtTopLevel, bool MultipleArchs, - const char *LinkingOutput, - InputInfo &Result) const { +InputInfo Driver::BuildJobsForAction(Compilation &C, const Action *A, + const ToolChain *TC, const char *BoundArch, + bool AtTopLevel, bool MultipleArchs, + const char *LinkingOutput) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); InputInfoList CudaDeviceInputInfos; if (const CudaHostAction *CHA = dyn_cast<CudaHostAction>(A)) { - InputInfo II; // Append outputs of device jobs to the input list. for (const Action *DA : CHA->getDeviceActions()) { - BuildJobsForAction(C, DA, TC, "", AtTopLevel, - /*MultipleArchs*/ false, LinkingOutput, II); - CudaDeviceInputInfos.push_back(II); + CudaDeviceInputInfos.push_back( + BuildJobsForAction(C, DA, TC, nullptr, AtTopLevel, + /*MultipleArchs*/ false, LinkingOutput)); } // Override current action with a real host compile action and continue // processing it. @@ -1765,11 +1805,9 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, Input.claim(); if (Input.getOption().matches(options::OPT_INPUT)) { const char *Name = Input.getValue(); - Result = InputInfo(Name, A->getType(), Name); - } else { - Result = InputInfo(&Input, A->getType(), ""); + return InputInfo(A, Name, /* BaseInput = */ Name); } - return; + return InputInfo(A, &Input, /* BaseInput = */ ""); } if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) { @@ -1783,30 +1821,37 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, else TC = &C.getDefaultToolChain(); - BuildJobsForAction(C, *BAA->begin(), TC, ArchName, AtTopLevel, - MultipleArchs, LinkingOutput, Result); - return; + return BuildJobsForAction(C, *BAA->begin(), TC, ArchName, AtTopLevel, + MultipleArchs, LinkingOutput); } if (const CudaDeviceAction *CDA = dyn_cast<CudaDeviceAction>(A)) { - // Figure out which NVPTX triple to use for device-side compilation based on - // whether host is 64-bit. - llvm::Triple DeviceTriple(C.getDefaultToolChain().getTriple().isArch64Bit() - ? "nvptx64-nvidia-cuda" - : "nvptx-nvidia-cuda"); - BuildJobsForAction(C, *CDA->begin(), - &getToolChain(C.getArgs(), DeviceTriple), - CDA->getGpuArchName(), CDA->isAtTopLevel(), - /*MultipleArchs*/ true, LinkingOutput, Result); - return; + // Initial processing of CudaDeviceAction carries host params. + // Call BuildJobsForAction() again, now with correct device parameters. + assert(CDA->getGpuArchName() && "No GPU name in device action."); + return BuildJobsForAction(C, *CDA->begin(), C.getCudaDeviceToolChain(), + CDA->getGpuArchName(), CDA->isAtTopLevel(), + /*MultipleArchs*/ true, LinkingOutput); } const ActionList *Inputs = &A->getInputs(); const JobAction *JA = cast<JobAction>(A); - const Tool *T = SelectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs); + const CudaHostAction *CollapsedCHA = nullptr; + const Tool *T = + selectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs, CollapsedCHA); if (!T) - return; + return InputInfo(); + + // If we've collapsed action list that contained CudaHostAction we + // need to build jobs for device-side inputs it may have held. + if (CollapsedCHA) { + for (const Action *DA : CollapsedCHA->getDeviceActions()) { + CudaDeviceInputInfos.push_back( + BuildJobsForAction(C, DA, TC, "", AtTopLevel, + /*MultipleArchs*/ false, LinkingOutput)); + } + } // Only use pipes when there is exactly one input. InputInfoList InputInfos; @@ -1814,14 +1859,11 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, // Treat dsymutil and verify sub-jobs as being at the top-level too, they // shouldn't get temporary output names. // FIXME: Clean this up. - bool SubJobAtTopLevel = false; - if (AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A))) - SubJobAtTopLevel = true; - - InputInfo II; - BuildJobsForAction(C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, - LinkingOutput, II); - InputInfos.push_back(II); + bool SubJobAtTopLevel = + AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A)); + InputInfos.push_back(BuildJobsForAction(C, Input, TC, BoundArch, + SubJobAtTopLevel, MultipleArchs, + LinkingOutput)); } // Always use the first input as the base input. @@ -1837,12 +1879,13 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, InputInfos.append(CudaDeviceInputInfos.begin(), CudaDeviceInputInfos.end()); // Determine the place to write output to, if any. + InputInfo Result; if (JA->getType() == types::TY_Nothing) - Result = InputInfo(A->getType(), BaseInput); + Result = InputInfo(A, BaseInput); else - Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, BoundArch, - AtTopLevel, MultipleArchs), - A->getType(), BaseInput); + Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch, + AtTopLevel, MultipleArchs), + BaseInput); if (CCCPrintBindings && !CCGenDiagnostics) { llvm::errs() << "# \"" << T->getToolChain().getTripleString() << '"' @@ -1857,6 +1900,7 @@ void Driver::BuildJobsForAction(Compilation &C, const Action *A, T->ConstructJob(C, *JA, Result, InputInfos, C.getArgsForToolChain(TC, BoundArch), LinkingOutput); } + return Result; } const char *Driver::getDefaultImageName() const { @@ -2091,6 +2135,11 @@ void Driver::generatePrefixedToolNames( // FIXME: Needs a better variable than DefaultTargetTriple Names.emplace_back(DefaultTargetTriple + "-" + Tool); Names.emplace_back(Tool); + + // Allow the discovery of tools prefixed with LLVM's default target triple. + std::string LLVMDefaultTargetTriple = llvm::sys::getDefaultTargetTriple(); + if (LLVMDefaultTargetTriple != DefaultTargetTriple) + Names.emplace_back(LLVMDefaultTargetTriple + "-" + Tool); } static bool ScanDirForExecutable(SmallString<128> &Dir, @@ -2163,6 +2212,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Darwin: case llvm::Triple::MacOSX: case llvm::Triple::IOS: + case llvm::Triple::TvOS: + case llvm::Triple::WatchOS: TC = new toolchains::DarwinClang(*this, Target, Args); break; case llvm::Triple::DragonFly: @@ -2185,16 +2236,22 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, break; case llvm::Triple::Linux: if (Target.getArch() == llvm::Triple::hexagon) - TC = new toolchains::Hexagon_TC(*this, Target, Args); + TC = new toolchains::HexagonToolChain(*this, Target, Args); + else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) && + !Target.hasEnvironment()) + TC = new toolchains::MipsLLVMToolChain(*this, Target, Args); else TC = new toolchains::Linux(*this, Target, Args); break; case llvm::Triple::NaCl: - TC = new toolchains::NaCl_TC(*this, Target, Args); + TC = new toolchains::NaClToolChain(*this, Target, Args); break; case llvm::Triple::Solaris: TC = new toolchains::Solaris(*this, Target, Args); break; + case llvm::Triple::AMDHSA: + TC = new toolchains::AMDGPUToolChain(*this, Target, Args); + break; case llvm::Triple::Win32: switch (Target.getEnvironment()) { default: @@ -2220,24 +2277,36 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::CUDA: TC = new toolchains::CudaToolChain(*this, Target, Args); break; + case llvm::Triple::PS4: + TC = new toolchains::PS4CPU(*this, Target, Args); + break; default: // Of these targets, Hexagon is the only one that might have // an OS of Linux, in which case it got handled above already. - if (Target.getArchName() == "tce") + switch (Target.getArch()) { + case llvm::Triple::tce: TC = new toolchains::TCEToolChain(*this, Target, Args); - else if (Target.getArch() == llvm::Triple::hexagon) - TC = new toolchains::Hexagon_TC(*this, Target, Args); - else if (Target.getArch() == llvm::Triple::xcore) - TC = new toolchains::XCore(*this, Target, Args); - else if (Target.getArch() == llvm::Triple::shave) - TC = new toolchains::SHAVEToolChain(*this, Target, Args); - else if (Target.isOSBinFormatELF()) - TC = new toolchains::Generic_ELF(*this, Target, Args); - else if (Target.isOSBinFormatMachO()) - TC = new toolchains::MachO(*this, Target, Args); - else - TC = new toolchains::Generic_GCC(*this, Target, Args); - break; + break; + case llvm::Triple::hexagon: + TC = new toolchains::HexagonToolChain(*this, Target, Args); + break; + case llvm::Triple::xcore: + TC = new toolchains::XCoreToolChain(*this, Target, Args); + break; + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: + TC = new toolchains::WebAssembly(*this, Target, Args); + break; + default: + if (Target.getVendor() == llvm::Triple::Myriad) + TC = new toolchains::MyriadToolChain(*this, Target, Args); + else if (Target.isOSBinFormatELF()) + TC = new toolchains::Generic_ELF(*this, Target, Args); + else if (Target.isOSBinFormatMachO()) + TC = new toolchains::MachO(*this, Target, Args); + else + TC = new toolchains::Generic_GCC(*this, Target, Args); + } } } return *TC; |