TargetSelect.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //===-- TargetSelect.cpp - Target Chooser Code ----------------------------===//
  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. // This just asks the TargetRegistry for the appropriate target to use, and
  10. // allows the user to specify a specific one on the commandline with -march=x,
  11. // -mcpu=y, and -mattr=a,-b,+c. Clients should initialize targets prior to
  12. // calling selectTarget().
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "llvm/ADT/Triple.h"
  16. #include "llvm/ExecutionEngine/ExecutionEngine.h"
  17. #include "llvm/IR/Module.h"
  18. #include "llvm/MC/SubtargetFeature.h"
  19. #include "llvm/MC/TargetRegistry.h"
  20. #include "llvm/Support/Host.h"
  21. #include "llvm/Target/TargetMachine.h"
  22. using namespace llvm;
  23. TargetMachine *EngineBuilder::selectTarget() {
  24. Triple TT;
  25. // MCJIT can generate code for remote targets, but the old JIT and Interpreter
  26. // must use the host architecture.
  27. if (WhichEngine != EngineKind::Interpreter && M)
  28. TT.setTriple(M->getTargetTriple());
  29. return selectTarget(TT, MArch, MCPU, MAttrs);
  30. }
  31. /// selectTarget - Pick a target either via -march or by guessing the native
  32. /// arch. Add any CPU features specified via -mcpu or -mattr.
  33. TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
  34. StringRef MArch,
  35. StringRef MCPU,
  36. const SmallVectorImpl<std::string>& MAttrs) {
  37. Triple TheTriple(TargetTriple);
  38. if (TheTriple.getTriple().empty())
  39. TheTriple.setTriple(sys::getProcessTriple());
  40. // Adjust the triple to match what the user requested.
  41. const Target *TheTarget = nullptr;
  42. if (!MArch.empty()) {
  43. auto I = find_if(TargetRegistry::targets(),
  44. [&](const Target &T) { return MArch == T.getName(); });
  45. if (I == TargetRegistry::targets().end()) {
  46. if (ErrorStr)
  47. *ErrorStr = "No available targets are compatible with this -march, "
  48. "see -version for the available targets.\n";
  49. return nullptr;
  50. }
  51. TheTarget = &*I;
  52. // Adjust the triple to match (if known), otherwise stick with the
  53. // requested/host triple.
  54. Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
  55. if (Type != Triple::UnknownArch)
  56. TheTriple.setArch(Type);
  57. } else {
  58. std::string Error;
  59. TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
  60. if (!TheTarget) {
  61. if (ErrorStr)
  62. *ErrorStr = Error;
  63. return nullptr;
  64. }
  65. }
  66. // Package up features to be passed to target/subtarget
  67. std::string FeaturesStr;
  68. if (!MAttrs.empty()) {
  69. SubtargetFeatures Features;
  70. for (unsigned i = 0; i != MAttrs.size(); ++i)
  71. Features.AddFeature(MAttrs[i]);
  72. FeaturesStr = Features.getString();
  73. }
  74. // Allocate a target...
  75. TargetMachine *Target =
  76. TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr,
  77. Options, RelocModel, CMModel, OptLevel,
  78. /*JIT*/ true);
  79. Target->Options.EmulatedTLS = EmulatedTLS;
  80. Target->Options.ExplicitEmulatedTLS = true;
  81. assert(Target && "Could not allocate target machine!");
  82. return Target;
  83. }