LlvmState.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //===-- LlvmState.cpp -------------------------------------------*- 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. #include "LlvmState.h"
  9. #include "Target.h"
  10. #include "llvm/ADT/SmallVector.h"
  11. #include "llvm/MC/MCCodeEmitter.h"
  12. #include "llvm/MC/MCContext.h"
  13. #include "llvm/MC/MCFixup.h"
  14. #include "llvm/MC/MCObjectFileInfo.h"
  15. #include "llvm/MC/TargetRegistry.h"
  16. #include "llvm/Support/Host.h"
  17. #include "llvm/Support/raw_ostream.h"
  18. #include "llvm/Target/TargetMachine.h"
  19. #include "llvm/Target/TargetOptions.h"
  20. namespace llvm {
  21. namespace exegesis {
  22. Expected<LLVMState> LLVMState::Create(std::string TripleName,
  23. std::string CpuName,
  24. const StringRef Features) {
  25. if (TripleName.empty())
  26. TripleName = Triple::normalize(sys::getDefaultTargetTriple());
  27. Triple TheTriple(TripleName);
  28. // Get the target specific parser.
  29. std::string Error;
  30. const Target *TheTarget =
  31. TargetRegistry::lookupTarget(/*MArch=*/"", TheTriple, Error);
  32. if (!TheTarget) {
  33. return llvm::make_error<llvm::StringError>("no LLVM target for triple " +
  34. TripleName,
  35. llvm::inconvertibleErrorCode());
  36. }
  37. // Update Triple with the updated triple from the target lookup.
  38. TripleName = TheTriple.str();
  39. if (CpuName == "native")
  40. CpuName = std::string(llvm::sys::getHostCPUName());
  41. std::unique_ptr<MCSubtargetInfo> STI(
  42. TheTarget->createMCSubtargetInfo(TripleName, CpuName, ""));
  43. assert(STI && "Unable to create subtarget info!");
  44. if (!STI->isCPUStringValid(CpuName)) {
  45. return llvm::make_error<llvm::StringError>(Twine("invalid CPU name (")
  46. .concat(CpuName)
  47. .concat(") for triple ")
  48. .concat(TripleName),
  49. llvm::inconvertibleErrorCode());
  50. }
  51. const TargetOptions Options;
  52. std::unique_ptr<const TargetMachine> TM(
  53. static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine(
  54. TripleName, CpuName, Features, Options, Reloc::Model::Static)));
  55. if (!TM) {
  56. return llvm::make_error<llvm::StringError>(
  57. "unable to create target machine", llvm::inconvertibleErrorCode());
  58. }
  59. const ExegesisTarget *ET =
  60. TripleName.empty() ? &ExegesisTarget::getDefault()
  61. : ExegesisTarget::lookup(TM->getTargetTriple());
  62. if (!ET) {
  63. return llvm::make_error<llvm::StringError>(
  64. "no Exegesis target for triple " + TripleName,
  65. llvm::inconvertibleErrorCode());
  66. }
  67. return LLVMState(std::move(TM), ET, CpuName);
  68. }
  69. LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,
  70. const ExegesisTarget *ET, const StringRef CpuName)
  71. : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)),
  72. OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),
  73. RegNameToRegNoMapping(createRegNameToRegNoMapping()) {
  74. PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName);
  75. BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());
  76. for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters())
  77. ReservedRegs.set(Reg);
  78. RATC.reset(
  79. new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs)));
  80. IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));
  81. }
  82. std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const {
  83. return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
  84. TheTargetMachine->getTarget().createTargetMachine(
  85. TheTargetMachine->getTargetTriple().normalize(),
  86. TheTargetMachine->getTargetCPU(),
  87. TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options,
  88. Reloc::Model::Static)));
  89. }
  90. std::unique_ptr<const DenseMap<StringRef, unsigned>>
  91. LLVMState::createOpcodeNameToOpcodeIdxMapping() const {
  92. const MCInstrInfo &InstrInfo = getInstrInfo();
  93. auto Map = std::make_unique<DenseMap<StringRef, unsigned>>(
  94. InstrInfo.getNumOpcodes());
  95. for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I)
  96. (*Map)[InstrInfo.getName(I)] = I;
  97. assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed");
  98. return std::move(Map);
  99. }
  100. std::unique_ptr<const DenseMap<StringRef, unsigned>>
  101. LLVMState::createRegNameToRegNoMapping() const {
  102. const MCRegisterInfo &RegInfo = getRegInfo();
  103. auto Map =
  104. std::make_unique<DenseMap<StringRef, unsigned>>(RegInfo.getNumRegs());
  105. // Special-case RegNo 0, which would otherwise be spelled as ''.
  106. (*Map)[kNoRegister] = 0;
  107. for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I)
  108. (*Map)[RegInfo.getName(I)] = I;
  109. assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed");
  110. return std::move(Map);
  111. }
  112. bool LLVMState::canAssemble(const MCInst &Inst) const {
  113. MCContext Context(TheTargetMachine->getTargetTriple(),
  114. TheTargetMachine->getMCAsmInfo(),
  115. TheTargetMachine->getMCRegisterInfo(),
  116. TheTargetMachine->getMCSubtargetInfo());
  117. std::unique_ptr<const MCCodeEmitter> CodeEmitter(
  118. TheTargetMachine->getTarget().createMCCodeEmitter(
  119. *TheTargetMachine->getMCInstrInfo(), Context));
  120. assert(CodeEmitter && "unable to create code emitter");
  121. SmallVector<char, 16> Tmp;
  122. raw_svector_ostream OS(Tmp);
  123. SmallVector<MCFixup, 4> Fixups;
  124. CodeEmitter->encodeInstruction(Inst, OS, Fixups,
  125. *TheTargetMachine->getMCSubtargetInfo());
  126. return Tmp.size() > 0;
  127. }
  128. } // namespace exegesis
  129. } // namespace llvm