LLVMTargetMachine.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
  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 file implements the LLVMTargetMachine class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Analysis/Passes.h"
  13. #include "llvm/CodeGen/AsmPrinter.h"
  14. #include "llvm/CodeGen/BasicTTIImpl.h"
  15. #include "llvm/CodeGen/MachineModuleInfo.h"
  16. #include "llvm/CodeGen/Passes.h"
  17. #include "llvm/CodeGen/TargetPassConfig.h"
  18. #include "llvm/IR/LegacyPassManager.h"
  19. #include "llvm/MC/MCAsmBackend.h"
  20. #include "llvm/MC/MCAsmInfo.h"
  21. #include "llvm/MC/MCCodeEmitter.h"
  22. #include "llvm/MC/MCContext.h"
  23. #include "llvm/MC/MCInstrInfo.h"
  24. #include "llvm/MC/MCObjectWriter.h"
  25. #include "llvm/MC/MCRegisterInfo.h"
  26. #include "llvm/MC/MCStreamer.h"
  27. #include "llvm/MC/MCSubtargetInfo.h"
  28. #include "llvm/MC/TargetRegistry.h"
  29. #include "llvm/Support/CommandLine.h"
  30. #include "llvm/Support/FormattedStream.h"
  31. #include "llvm/Target/TargetMachine.h"
  32. #include "llvm/Target/TargetOptions.h"
  33. using namespace llvm;
  34. static cl::opt<bool>
  35. EnableTrapUnreachable("trap-unreachable", cl::Hidden,
  36. cl::desc("Enable generating trap for unreachable"));
  37. void LLVMTargetMachine::initAsmInfo() {
  38. MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
  39. assert(MRI && "Unable to create reg info");
  40. MII.reset(TheTarget.createMCInstrInfo());
  41. assert(MII && "Unable to create instruction info");
  42. // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
  43. // to some backends having subtarget feature dependent module level
  44. // code generation. This is similar to the hack in the AsmPrinter for
  45. // module level assembly etc.
  46. STI.reset(TheTarget.createMCSubtargetInfo(
  47. getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
  48. assert(STI && "Unable to create subtarget info");
  49. MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
  50. *MRI, getTargetTriple().str(), Options.MCOptions);
  51. // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
  52. // and if the old one gets included then MCAsmInfo will be NULL and
  53. // we'll crash later.
  54. // Provide the user with a useful error message about what's wrong.
  55. assert(TmpAsmInfo && "MCAsmInfo not initialized. "
  56. "Make sure you include the correct TargetSelect.h"
  57. "and that InitializeAllTargetMCs() is being invoked!");
  58. if (Options.BinutilsVersion.first > 0)
  59. TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
  60. if (Options.DisableIntegratedAS) {
  61. TmpAsmInfo->setUseIntegratedAssembler(false);
  62. // If there is explict option disable integratedAS, we can't use it for
  63. // inlineasm either.
  64. TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
  65. }
  66. TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
  67. TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections);
  68. TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);
  69. if (Options.ExceptionModel != ExceptionHandling::None)
  70. TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
  71. AsmInfo.reset(TmpAsmInfo);
  72. }
  73. LLVMTargetMachine::LLVMTargetMachine(const Target &T,
  74. StringRef DataLayoutString,
  75. const Triple &TT, StringRef CPU,
  76. StringRef FS, const TargetOptions &Options,
  77. Reloc::Model RM, CodeModel::Model CM,
  78. CodeGenOpt::Level OL)
  79. : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
  80. this->RM = RM;
  81. this->CMModel = CM;
  82. this->OptLevel = OL;
  83. if (EnableTrapUnreachable)
  84. this->Options.TrapUnreachable = true;
  85. }
  86. TargetTransformInfo
  87. LLVMTargetMachine::getTargetTransformInfo(const Function &F) const {
  88. return TargetTransformInfo(BasicTTIImpl(this, F));
  89. }
  90. /// addPassesToX helper drives creation and initialization of TargetPassConfig.
  91. static TargetPassConfig *
  92. addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
  93. bool DisableVerify,
  94. MachineModuleInfoWrapperPass &MMIWP) {
  95. // Targets may override createPassConfig to provide a target-specific
  96. // subclass.
  97. TargetPassConfig *PassConfig = TM.createPassConfig(PM);
  98. // Set PassConfig options provided by TargetMachine.
  99. PassConfig->setDisableVerify(DisableVerify);
  100. PM.add(PassConfig);
  101. PM.add(&MMIWP);
  102. if (PassConfig->addISelPasses())
  103. return nullptr;
  104. PassConfig->addMachinePasses();
  105. PassConfig->setInitialized();
  106. return PassConfig;
  107. }
  108. bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
  109. raw_pwrite_stream &Out,
  110. raw_pwrite_stream *DwoOut,
  111. CodeGenFileType FileType,
  112. MCContext &Context) {
  113. Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
  114. createMCStreamer(Out, DwoOut, FileType, Context);
  115. if (auto Err = MCStreamerOrErr.takeError())
  116. return true;
  117. // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
  118. FunctionPass *Printer =
  119. getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
  120. if (!Printer)
  121. return true;
  122. PM.add(Printer);
  123. return false;
  124. }
  125. Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
  126. raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
  127. MCContext &Context) {
  128. if (Options.MCOptions.MCSaveTempLabels)
  129. Context.setAllowTemporaryLabels(false);
  130. const MCSubtargetInfo &STI = *getMCSubtargetInfo();
  131. const MCAsmInfo &MAI = *getMCAsmInfo();
  132. const MCRegisterInfo &MRI = *getMCRegisterInfo();
  133. const MCInstrInfo &MII = *getMCInstrInfo();
  134. std::unique_ptr<MCStreamer> AsmStreamer;
  135. switch (FileType) {
  136. case CGFT_AssemblyFile: {
  137. MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
  138. getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
  139. // Create a code emitter if asked to show the encoding.
  140. std::unique_ptr<MCCodeEmitter> MCE;
  141. if (Options.MCOptions.ShowMCEncoding)
  142. MCE.reset(getTarget().createMCCodeEmitter(MII, Context));
  143. bool UseDwarfDirectory = false;
  144. switch (Options.MCOptions.MCUseDwarfDirectory) {
  145. case MCTargetOptions::DisableDwarfDirectory:
  146. UseDwarfDirectory = false;
  147. break;
  148. case MCTargetOptions::EnableDwarfDirectory:
  149. UseDwarfDirectory = true;
  150. break;
  151. case MCTargetOptions::DefaultDwarfDirectory:
  152. UseDwarfDirectory = MAI.enableDwarfFileDirectoryDefault();
  153. break;
  154. }
  155. std::unique_ptr<MCAsmBackend> MAB(
  156. getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
  157. auto FOut = std::make_unique<formatted_raw_ostream>(Out);
  158. MCStreamer *S = getTarget().createAsmStreamer(
  159. Context, std::move(FOut), Options.MCOptions.AsmVerbose,
  160. UseDwarfDirectory, InstPrinter, std::move(MCE), std::move(MAB),
  161. Options.MCOptions.ShowMCInst);
  162. AsmStreamer.reset(S);
  163. break;
  164. }
  165. case CGFT_ObjectFile: {
  166. // Create the code emitter for the target if it exists. If not, .o file
  167. // emission fails.
  168. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
  169. if (!MCE)
  170. return make_error<StringError>("createMCCodeEmitter failed",
  171. inconvertibleErrorCode());
  172. MCAsmBackend *MAB =
  173. getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
  174. if (!MAB)
  175. return make_error<StringError>("createMCAsmBackend failed",
  176. inconvertibleErrorCode());
  177. Triple T(getTargetTriple().str());
  178. AsmStreamer.reset(getTarget().createMCObjectStreamer(
  179. T, Context, std::unique_ptr<MCAsmBackend>(MAB),
  180. DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
  181. : MAB->createObjectWriter(Out),
  182. std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
  183. Options.MCOptions.MCIncrementalLinkerCompatible,
  184. /*DWARFMustBeAtTheEnd*/ true));
  185. break;
  186. }
  187. case CGFT_Null:
  188. // The Null output is intended for use for performance analysis and testing,
  189. // not real users.
  190. AsmStreamer.reset(getTarget().createNullStreamer(Context));
  191. break;
  192. }
  193. return std::move(AsmStreamer);
  194. }
  195. bool LLVMTargetMachine::addPassesToEmitFile(
  196. PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
  197. CodeGenFileType FileType, bool DisableVerify,
  198. MachineModuleInfoWrapperPass *MMIWP) {
  199. // Add common CodeGen passes.
  200. if (!MMIWP)
  201. MMIWP = new MachineModuleInfoWrapperPass(this);
  202. TargetPassConfig *PassConfig =
  203. addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
  204. if (!PassConfig)
  205. return true;
  206. if (TargetPassConfig::willCompleteCodeGenPipeline()) {
  207. if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
  208. return true;
  209. } else {
  210. // MIR printing is redundant with -filetype=null.
  211. if (FileType != CGFT_Null)
  212. PM.add(createPrintMIRPass(Out));
  213. }
  214. PM.add(createFreeMachineFunctionPass());
  215. return false;
  216. }
  217. /// addPassesToEmitMC - Add passes to the specified pass manager to get
  218. /// machine code emitted with the MCJIT. This method returns true if machine
  219. /// code is not supported. It fills the MCContext Ctx pointer which can be
  220. /// used to build custom MCStreamer.
  221. ///
  222. bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
  223. raw_pwrite_stream &Out,
  224. bool DisableVerify) {
  225. // Add common CodeGen passes.
  226. MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
  227. TargetPassConfig *PassConfig =
  228. addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
  229. if (!PassConfig)
  230. return true;
  231. assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
  232. "Cannot emit MC with limited codegen pipeline");
  233. Ctx = &MMIWP->getMMI().getContext();
  234. // libunwind is unable to load compact unwind dynamically, so we must generate
  235. // DWARF unwind info for the JIT.
  236. Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
  237. if (Options.MCOptions.MCSaveTempLabels)
  238. Ctx->setAllowTemporaryLabels(false);
  239. // Create the code emitter for the target if it exists. If not, .o file
  240. // emission fails.
  241. const MCSubtargetInfo &STI = *getMCSubtargetInfo();
  242. const MCRegisterInfo &MRI = *getMCRegisterInfo();
  243. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx);
  244. MCAsmBackend *MAB =
  245. getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
  246. if (!MCE || !MAB)
  247. return true;
  248. const Triple &T = getTargetTriple();
  249. std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
  250. T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
  251. std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
  252. Options.MCOptions.MCIncrementalLinkerCompatible,
  253. /*DWARFMustBeAtTheEnd*/ true));
  254. // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
  255. FunctionPass *Printer =
  256. getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
  257. if (!Printer)
  258. return true;
  259. PM.add(Printer);
  260. PM.add(createFreeMachineFunctionPass());
  261. return false; // success!
  262. }