brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.3 KiB · a8acf9c Raw
611 lines · cpp
1//===--- AIX.cpp - AIX ToolChain Implementations ----------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "AIX.h"10#include "clang/Driver/CommonArgs.h"11#include "clang/Driver/Compilation.h"12#include "clang/Driver/SanitizerArgs.h"13#include "clang/Options/Options.h"14#include "llvm/ADT/StringExtras.h"15#include "llvm/Option/ArgList.h"16#include "llvm/ProfileData/InstrProf.h"17#include "llvm/Support/Path.h"18 19#include <set>20 21using AIX = clang::driver::toolchains::AIX;22using namespace clang;23using namespace clang::driver;24using namespace clang::driver::tools;25using namespace clang::driver::toolchains;26 27using namespace llvm::opt;28using namespace llvm::sys;29 30void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,31                                  const InputInfo &Output,32                                  const InputInfoList &Inputs,33                                  const ArgList &Args,34                                  const char *LinkingOutput) const {35  const Driver &D = getToolChain().getDriver();36  ArgStringList CmdArgs;37 38  const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit();39  const bool IsArch64Bit = getToolChain().getTriple().isArch64Bit();40  // Only support 32 and 64 bit.41  if (!IsArch32Bit && !IsArch64Bit)42    llvm_unreachable("Unsupported bit width value.");43 44  if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) {45    D.Diag(diag::err_drv_unsupported_opt_for_target)46        << A->getSpelling() << D.getTargetTriple();47  }48 49  // Specify the mode in which the as(1) command operates.50  if (IsArch32Bit) {51    CmdArgs.push_back("-a32");52  } else {53    // Must be 64-bit, otherwise asserted already.54    CmdArgs.push_back("-a64");55  }56 57  // Accept any mixture of instructions.58  // On Power for AIX and Linux, this behaviour matches that of GCC for both the59  // user-provided assembler source case and the compiler-produced assembler60  // source case. Yet XL with user-provided assembler source would not add this.61  CmdArgs.push_back("-many");62 63  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);64 65  // Specify assembler output file.66  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");67  if (Output.isFilename()) {68    CmdArgs.push_back("-o");69    CmdArgs.push_back(Output.getFilename());70  }71 72  // Specify assembler input file.73  // The system assembler on AIX takes exactly one input file. The driver is74  // expected to invoke as(1) separately for each assembler source input file.75  if (Inputs.size() != 1)76    llvm_unreachable("Invalid number of input files.");77  const InputInfo &II = Inputs[0];78  assert((II.isFilename() || II.isNothing()) && "Invalid input.");79  if (II.isFilename())80    CmdArgs.push_back(II.getFilename());81 82  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));83  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),84                                         Exec, CmdArgs, Inputs, Output));85}86 87// Determine whether there are any linker options that supply an export list88// (or equivalent information about what to export) being sent to the linker.89static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) {90  for (size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) {91    llvm::StringRef ArgString(CmdArgs[i]);92 93    if (ArgString.starts_with("-bE:") || ArgString.starts_with("-bexport:") ||94        ArgString == "-bexpall" || ArgString == "-bexpfull")95      return true;96 97    // If we split -b option, check the next opt.98    if (ArgString == "-b" && i + 1 < Size) {99      ++i;100      llvm::StringRef ArgNextString(CmdArgs[i]);101      if (ArgNextString.starts_with("E:") ||102          ArgNextString.starts_with("export:") || ArgNextString == "expall" ||103          ArgNextString == "expfull")104        return true;105    }106  }107  return false;108}109 110void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,111                               const InputInfo &Output,112                               const InputInfoList &Inputs, const ArgList &Args,113                               const char *LinkingOutput) const {114  const AIX &ToolChain = static_cast<const AIX &>(getToolChain());115  const Driver &D = ToolChain.getDriver();116  ArgStringList CmdArgs;117 118  const bool IsArch32Bit = ToolChain.getTriple().isArch32Bit();119  const bool IsArch64Bit = ToolChain.getTriple().isArch64Bit();120  // Only support 32 and 64 bit.121  if (!(IsArch32Bit || IsArch64Bit))122    llvm_unreachable("Unsupported bit width value.");123 124  if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) {125    D.Diag(diag::err_drv_unsupported_opt_for_target)126        << A->getSpelling() << D.getTargetTriple();127  }128 129  // Force static linking when "-static" is present.130  if (Args.hasArg(options::OPT_static))131    CmdArgs.push_back("-bnso");132 133  // Add options for shared libraries.134  if (Args.hasArg(options::OPT_shared)) {135    CmdArgs.push_back("-bM:SRE");136    CmdArgs.push_back("-bnoentry");137  }138 139  if (Args.hasFlag(options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr,140                   false)) {141    if (Args.hasArg(options::OPT_shared))142      D.Diag(diag::err_roptr_cannot_build_shared);143 144    // The `-mxcoff-roptr` option places constants in RO sections as much as145    // possible. Then `-bforceimprw` changes such sections to RW if they contain146    // imported symbols that need to be resolved.147    CmdArgs.push_back("-bforceimprw");148  }149 150  // PGO instrumentation generates symbols belonging to special sections, and151  // the linker needs to place all symbols in a particular section together in152  // memory; the AIX linker does that under an option.153  if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,154                    false) ||155       Args.hasFlag(options::OPT_fprofile_generate,156                    options::OPT_fno_profile_generate, false) ||157       Args.hasFlag(options::OPT_fprofile_generate_EQ,158                    options::OPT_fno_profile_generate, false) ||159       Args.hasFlag(options::OPT_fprofile_instr_generate,160                    options::OPT_fno_profile_instr_generate, false) ||161       Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,162                    options::OPT_fno_profile_instr_generate, false) ||163       Args.hasFlag(options::OPT_fcs_profile_generate,164                    options::OPT_fno_profile_generate, false) ||165       Args.hasFlag(options::OPT_fcs_profile_generate_EQ,166                    options::OPT_fno_profile_generate, false) ||167       Args.hasArg(options::OPT_fcreate_profile) ||168       Args.hasArg(options::OPT_coverage))169    CmdArgs.push_back("-bdbg:namedsects:ss");170 171  if (Arg *A = Args.getLastArg(options::OPT_mxcoff_build_id_EQ)) {172    StringRef BuildId = A->getValue();173    if (BuildId[0] != '0' || BuildId[1] != 'x' ||174        BuildId.find_if_not(llvm::isHexDigit, 2) != StringRef::npos)175      ToolChain.getDriver().Diag(diag::err_drv_unsupported_option_argument)176          << A->getSpelling() << BuildId;177    else {178      std::string LinkerFlag = "-bdbg:ldrinfo:xcoff_binary_id:0x";179      if (BuildId.size() % 2) // Prepend a 0 if odd number of digits.180        LinkerFlag += "0";181      LinkerFlag += BuildId.drop_front(2).lower();182      CmdArgs.push_back(Args.MakeArgString(LinkerFlag));183    }184  }185 186  // Specify linker output file.187  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");188  if (Output.isFilename()) {189    CmdArgs.push_back("-o");190    CmdArgs.push_back(Output.getFilename());191  }192 193  // Set linking mode (i.e., 32/64-bit) and the address of194  // text and data sections based on arch bit width.195  if (IsArch32Bit) {196    CmdArgs.push_back("-b32");197    CmdArgs.push_back("-bpT:0x10000000");198    CmdArgs.push_back("-bpD:0x20000000");199  } else {200    // Must be 64-bit, otherwise asserted already.201    CmdArgs.push_back("-b64");202    CmdArgs.push_back("-bpT:0x100000000");203    CmdArgs.push_back("-bpD:0x110000000");204  }205 206  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,207                   options::OPT_shared, options::OPT_r)) {208    auto getCrt0Basename = [&Args, IsArch32Bit] {209      if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) {210        // Enable gprofiling when "-pg" is specified.211        if (A->getOption().matches(options::OPT_pg))212          return IsArch32Bit ? "gcrt0.o" : "gcrt0_64.o";213        // Enable profiling when "-p" is specified.214        return IsArch32Bit ? "mcrt0.o" : "mcrt0_64.o";215      }216      return IsArch32Bit ? "crt0.o" : "crt0_64.o";217    };218 219    CmdArgs.push_back(220        Args.MakeArgString(ToolChain.GetFilePath(getCrt0Basename())));221 222    CmdArgs.push_back(Args.MakeArgString(223        ToolChain.GetFilePath(IsArch32Bit ? "crti.o" : "crti_64.o")));224  }225 226  // Collect all static constructor and destructor functions in both C and CXX227  // language link invocations. This has to come before AddLinkerInputs as the228  // implied option needs to precede any other '-bcdtors' settings or229  // '-bnocdtors' that '-Wl' might forward.230  CmdArgs.push_back("-bcdtors:all:0:s");231 232  if (Args.hasArg(options::OPT_rpath)) {233    for (const auto &bopt : Args.getAllArgValues(options::OPT_b))234      // Check -b opts prefix for "libpath:" or exact match for "nolibpath"235      if (!bopt.rfind("libpath:", 0) || bopt == "nolibpath")236        D.Diag(diag::err_drv_cannot_mix_options) << "-rpath" << "-b" + bopt;237 238    for (const auto &wlopt : Args.getAllArgValues(options::OPT_Wl_COMMA))239      // Check -Wl, opts prefix for "-blibpath:" or exact match for240      // "-bnolibpath"241      if (!wlopt.rfind("-blibpath:", 0) || wlopt == "-bnolibpath")242        D.Diag(diag::err_drv_cannot_mix_options) << "-rpath" << "-Wl," + wlopt;243 244    for (const auto &xopt : Args.getAllArgValues(options::OPT_Xlinker))245      // Check -Xlinker opts prefix for "-blibpath:" or exact match for246      // "-bnolibpath"247      if (!xopt.rfind("-blibpath:", 0) || xopt == "-bnolibpath")248        D.Diag(diag::err_drv_cannot_mix_options)249            << "-rpath" << "-Xlinker " + xopt;250 251    std::string BlibPathStr = "";252    for (const auto &dir : Args.getAllArgValues(options::OPT_rpath))253      BlibPathStr += dir + ":";254    BlibPathStr += "/usr/lib:/lib";255    CmdArgs.push_back(Args.MakeArgString(Twine("-blibpath:") + BlibPathStr));256  }257 258  // Specify linker input file(s).259  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);260 261  if (D.isUsingLTO())262    addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs,263                  D.getLTOMode() == LTOK_Thin);264 265  if (Args.hasArg(options::OPT_shared) && !hasExportListLinkerOpts(CmdArgs)) {266 267    const char *CreateExportListExec = Args.MakeArgString(268        path::parent_path(ToolChain.getDriver().ClangExecutable) +269        "/llvm-nm");270    ArgStringList CreateExportCmdArgs;271 272    std::string CreateExportListPath =273        C.getDriver().GetTemporaryPath("CreateExportList", "exp");274    const char *ExportList =275        C.addTempFile(C.getArgs().MakeArgString(CreateExportListPath));276 277    for (const auto &II : Inputs)278      if (II.isFilename())279        CreateExportCmdArgs.push_back(II.getFilename());280 281    CreateExportCmdArgs.push_back("--export-symbols");282    CreateExportCmdArgs.push_back("-X");283    if (IsArch32Bit) {284      CreateExportCmdArgs.push_back("32");285    } else {286      // Must be 64-bit, otherwise asserted already.287      CreateExportCmdArgs.push_back("64");288    }289 290    auto ExpCommand = std::make_unique<Command>(291        JA, *this, ResponseFileSupport::None(), CreateExportListExec,292        CreateExportCmdArgs, Inputs, Output);293    ExpCommand->setRedirectFiles(294        {std::nullopt, std::string(ExportList), std::nullopt});295    C.addCommand(std::move(ExpCommand));296    CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-bE:") + ExportList));297  }298 299  // Add directory to library search path.300  Args.AddAllArgs(CmdArgs, options::OPT_L);301  if (!Args.hasArg(options::OPT_r)) {302    ToolChain.AddFilePathLibArgs(Args, CmdArgs);303    ToolChain.addProfileRTLibs(Args, CmdArgs);304 305    if (getToolChain().ShouldLinkCXXStdlib(Args))306      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);307 308    if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {309      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);310 311      // Add OpenMP runtime if -fopenmp is specified.312      if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,313                       options::OPT_fno_openmp, false)) {314        switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {315        case Driver::OMPRT_OMP:316          CmdArgs.push_back("-lomp");317          break;318        case Driver::OMPRT_IOMP5:319          CmdArgs.push_back("-liomp5");320          break;321        case Driver::OMPRT_GOMP:322          CmdArgs.push_back("-lgomp");323          break;324        case Driver::OMPRT_Unknown:325          // Already diagnosed.326          break;327        }328      }329 330      // Support POSIX threads if "-pthreads" or "-pthread" is present.331      if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))332        CmdArgs.push_back("-lpthreads");333 334      if (D.CCCIsCXX())335        CmdArgs.push_back("-lm");336 337      CmdArgs.push_back("-lc");338 339      if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) {340        CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) +341                                             "/lib/profiled"));342        CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) +343                                             "/usr/lib/profiled"));344      }345    }346  }347 348  if (D.IsFlangMode() &&349      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {350    ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);351    ToolChain.addFortranRuntimeLibs(Args, CmdArgs);352    CmdArgs.push_back("-lm");353    CmdArgs.push_back("-lpthread");354  }355  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());356  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),357                                         Exec, CmdArgs, Inputs, Output));358}359 360/// AIX - AIX tool chain which can call as(1) and ld(1) directly.361AIX::AIX(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)362    : ToolChain(D, Triple, Args) {363  getProgramPaths().push_back(getDriver().Dir);364 365  ParseInlineAsmUsingAsmParser = Args.hasFlag(366      options::OPT_fintegrated_as, options::OPT_fno_integrated_as, true);367  getLibraryPaths().push_back(getDriver().SysRoot + "/usr/lib");368}369 370// Returns the effective header sysroot path to use.371// This comes from either -isysroot or --sysroot.372llvm::StringRef373AIX::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const {374  if (DriverArgs.hasArg(options::OPT_isysroot))375    return DriverArgs.getLastArgValue(options::OPT_isysroot);376  if (!getDriver().SysRoot.empty())377    return getDriver().SysRoot;378  return "/";379}380 381void AIX::AddOpenMPIncludeArgs(const ArgList &DriverArgs,382                               ArgStringList &CC1Args) const {383  // Add OpenMP include paths if -fopenmp is specified.384  if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,385                         options::OPT_fno_openmp, false)) {386    SmallString<128> PathOpenMP;387    switch (getDriver().getOpenMPRuntime(DriverArgs)) {388    case Driver::OMPRT_OMP:389      PathOpenMP = GetHeaderSysroot(DriverArgs);390      llvm::sys::path::append(PathOpenMP, "opt/IBM/openxlCSDK", "include",391                              "openmp");392      addSystemInclude(DriverArgs, CC1Args, PathOpenMP.str());393      break;394    case Driver::OMPRT_IOMP5:395    case Driver::OMPRT_GOMP:396    case Driver::OMPRT_Unknown:397      // Unknown / unsupported include paths.398      break;399    }400  }401}402 403void AIX::AddClangSystemIncludeArgs(const ArgList &DriverArgs,404                                    ArgStringList &CC1Args) const {405  // Return if -nostdinc is specified as a driver option.406  if (DriverArgs.hasArg(options::OPT_nostdinc))407    return;408 409  llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);410  const Driver &D = getDriver();411 412  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {413    SmallString<128> P(D.ResourceDir);414    // Add the PowerPC intrinsic headers (<resource>/include/ppc_wrappers)415    path::append(P, "include", "ppc_wrappers");416    addSystemInclude(DriverArgs, CC1Args, P);417    // Add the Clang builtin headers (<resource>/include)418    addSystemInclude(DriverArgs, CC1Args, path::parent_path(P.str()));419  }420 421  // Add the include directory containing omp.h. This needs to be before422  // adding the system include directory because other compilers put their423  // omp.h in /usr/include.424  AddOpenMPIncludeArgs(DriverArgs, CC1Args);425 426  // Return if -nostdlibinc is specified as a driver option.427  if (DriverArgs.hasArg(options::OPT_nostdlibinc))428    return;429 430  // Add <sysroot>/usr/include.431  SmallString<128> UP(Sysroot);432  path::append(UP, "/usr/include");433  addSystemInclude(DriverArgs, CC1Args, UP.str());434}435 436void AIX::AddClangCXXStdlibIncludeArgs(437    const llvm::opt::ArgList &DriverArgs,438    llvm::opt::ArgStringList &CC1Args) const {439 440  if (DriverArgs.hasArg(options::OPT_nostdinc) ||441      DriverArgs.hasArg(options::OPT_nostdincxx) ||442      DriverArgs.hasArg(options::OPT_nostdlibinc))443    return;444 445  switch (GetCXXStdlibType(DriverArgs)) {446  case ToolChain::CST_Libstdcxx:447    llvm::report_fatal_error(448        "picking up libstdc++ headers is unimplemented on AIX");449  case ToolChain::CST_Libcxx: {450    llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);451    SmallString<128> PathCPP(Sysroot);452    llvm::sys::path::append(PathCPP, "opt/IBM/openxlCSDK", "include", "c++",453                            "v1");454    addSystemInclude(DriverArgs, CC1Args, PathCPP.str());455    // Required in order to suppress conflicting C++ overloads in the system456    // libc headers that were used by XL C++.457    CC1Args.push_back("-D__LIBC_NO_CPP_MATH_OVERLOADS__");458    return;459  }460  }461 462  llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");463}464 465void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,466                              llvm::opt::ArgStringList &CmdArgs) const {467  switch (GetCXXStdlibType(Args)) {468  case ToolChain::CST_Libstdcxx:469    llvm::report_fatal_error("linking libstdc++ unimplemented on AIX");470  case ToolChain::CST_Libcxx:471    CmdArgs.push_back("-lc++");472    if (Args.hasArg(options::OPT_fexperimental_library))473      CmdArgs.push_back("-lc++experimental");474    CmdArgs.push_back("-lc++abi");475    return;476  }477 478  llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");479}480 481// This function processes all the mtocdata options to build the final482// simplified toc data options to pass to CC1.483static void addTocDataOptions(const llvm::opt::ArgList &Args,484                              llvm::opt::ArgStringList &CC1Args,485                              const Driver &D) {486 487  // Check the global toc-data setting. The default is -mno-tocdata.488  // To enable toc-data globally, -mtocdata must be specified.489  // Additionally, it must be last to take effect.490  const bool TOCDataGloballyinEffect = [&Args]() {491    if (const Arg *LastArg =492            Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))493      return LastArg->getOption().matches(options::OPT_mtocdata);494    else495      return false;496  }();497 498  enum TOCDataSetting {499    AddressInTOC = 0, // Address of the symbol stored in the TOC.500    DataInTOC = 1     // Symbol defined in the TOC.501  };502 503  const TOCDataSetting DefaultTocDataSetting =504      TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;505 506  // Process the list of variables in the explicitly specified options507  // -mtocdata= and -mno-tocdata= to see which variables are opposite to508  // the global setting of tocdata in TOCDataGloballyinEffect.509  // Those that have the opposite setting to TOCDataGloballyinEffect, are added510  // to ExplicitlySpecifiedGlobals.511  std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;512  for (const auto Arg :513       Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {514    TOCDataSetting ArgTocDataSetting =515        Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC516                                                           : AddressInTOC;517 518    if (ArgTocDataSetting != DefaultTocDataSetting)519      for (const char *Val : Arg->getValues())520        ExplicitlySpecifiedGlobals.insert(Val);521    else522      for (const char *Val : Arg->getValues())523        ExplicitlySpecifiedGlobals.erase(Val);524  }525 526  auto buildExceptionList = [](const std::set<llvm::StringRef> &ExplicitValues,527                               const char *OptionSpelling) {528    std::string Option(OptionSpelling);529    bool IsFirst = true;530    for (const auto &E : ExplicitValues) {531      if (!IsFirst)532        Option += ",";533 534      IsFirst = false;535      Option += E.str();536    }537    return Option;538  };539 540  // Pass the final tocdata options to CC1 consisting of the default541  // tocdata option (-mtocdata/-mno-tocdata) along with the list542  // option (-mno-tocdata=/-mtocdata=) if there are any explicitly specified543  // variables which would be exceptions to the default setting.544  const char *TocDataGlobalOption =545      TOCDataGloballyinEffect ? "-mtocdata" : "-mno-tocdata";546  CC1Args.push_back(TocDataGlobalOption);547 548  const char *TocDataListOption =549      TOCDataGloballyinEffect ? "-mno-tocdata=" : "-mtocdata=";550  if (!ExplicitlySpecifiedGlobals.empty())551    CC1Args.push_back(Args.MakeArgString(llvm::Twine(552        buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));553}554 555void AIX::addClangTargetOptions(556    const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,557    Action::OffloadKind DeviceOffloadingKind) const {558  Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);559  Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);560  Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);561 562  // Forward last mtocdata/mno_tocdata options to -cc1.563  if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,564                  options::OPT_mtocdata))565    addTocDataOptions(Args, CC1Args, getDriver());566 567  if (Args.hasArg(options::OPT_msave_reg_params))568    CC1Args.push_back("-msave-reg-params");569 570  if (Args.hasFlag(options::OPT_fxl_pragma_pack,571                   options::OPT_fno_xl_pragma_pack, true))572    CC1Args.push_back("-fxl-pragma-pack");573 574  // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled575  // or disabled sized deallocations.576  if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,577                              options::OPT_fno_sized_deallocation))578    CC1Args.push_back("-fno-sized-deallocation");579}580 581void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,582                           llvm::opt::ArgStringList &CmdArgs) const {583  if (needsProfileRT(Args)) {584    // Add linker option -u__llvm_profile_runtime to cause runtime585    // initialization to occur.586    CmdArgs.push_back(Args.MakeArgString(587        Twine("-u", llvm::getInstrProfRuntimeHookVarName())));588 589    if (const auto *A =590            Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {591      StringRef Val = A->getValue();592      if (Val == "atomic" || Val == "prefer-atomic")593        CmdArgs.push_back("-latomic");594    }595  }596 597  ToolChain::addProfileRTLibs(Args, CmdArgs);598}599 600ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {601  return ToolChain::CST_Libcxx;602}603 604ToolChain::RuntimeLibType AIX::GetDefaultRuntimeLibType() const {605  return ToolChain::RLT_CompilerRT;606}607 608auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); }609 610auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); }611