TargetMachineC.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. //===-- TargetMachine.cpp -------------------------------------------------===//
  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 LLVM-C part of TargetMachine.h
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm-c/Core.h"
  13. #include "llvm-c/Target.h"
  14. #include "llvm-c/TargetMachine.h"
  15. #include "llvm/Analysis/TargetTransformInfo.h"
  16. #include "llvm/IR/DataLayout.h"
  17. #include "llvm/IR/LegacyPassManager.h"
  18. #include "llvm/IR/Module.h"
  19. #include "llvm/MC/SubtargetFeature.h"
  20. #include "llvm/MC/TargetRegistry.h"
  21. #include "llvm/Support/FileSystem.h"
  22. #include "llvm/Support/FormattedStream.h"
  23. #include "llvm/Support/Host.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. #include "llvm/Target/CodeGenCWrappers.h"
  26. #include "llvm/Target/TargetMachine.h"
  27. #include <cassert>
  28. #include <cstdlib>
  29. #include <cstring>
  30. using namespace llvm;
  31. static TargetMachine *unwrap(LLVMTargetMachineRef P) {
  32. return reinterpret_cast<TargetMachine *>(P);
  33. }
  34. static Target *unwrap(LLVMTargetRef P) {
  35. return reinterpret_cast<Target*>(P);
  36. }
  37. static LLVMTargetMachineRef wrap(const TargetMachine *P) {
  38. return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
  39. }
  40. static LLVMTargetRef wrap(const Target * P) {
  41. return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
  42. }
  43. LLVMTargetRef LLVMGetFirstTarget() {
  44. if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
  45. return nullptr;
  46. }
  47. const Target *target = &*TargetRegistry::targets().begin();
  48. return wrap(target);
  49. }
  50. LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
  51. return wrap(unwrap(T)->getNext());
  52. }
  53. LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
  54. StringRef NameRef = Name;
  55. auto I = find_if(TargetRegistry::targets(),
  56. [&](const Target &T) { return T.getName() == NameRef; });
  57. return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;
  58. }
  59. LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
  60. char **ErrorMessage) {
  61. std::string Error;
  62. *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
  63. if (!*T) {
  64. if (ErrorMessage)
  65. *ErrorMessage = strdup(Error.c_str());
  66. return 1;
  67. }
  68. return 0;
  69. }
  70. const char * LLVMGetTargetName(LLVMTargetRef T) {
  71. return unwrap(T)->getName();
  72. }
  73. const char * LLVMGetTargetDescription(LLVMTargetRef T) {
  74. return unwrap(T)->getShortDescription();
  75. }
  76. LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
  77. return unwrap(T)->hasJIT();
  78. }
  79. LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
  80. return unwrap(T)->hasTargetMachine();
  81. }
  82. LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
  83. return unwrap(T)->hasMCAsmBackend();
  84. }
  85. LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
  86. const char *Triple, const char *CPU, const char *Features,
  87. LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
  88. LLVMCodeModel CodeModel) {
  89. Optional<Reloc::Model> RM;
  90. switch (Reloc){
  91. case LLVMRelocStatic:
  92. RM = Reloc::Static;
  93. break;
  94. case LLVMRelocPIC:
  95. RM = Reloc::PIC_;
  96. break;
  97. case LLVMRelocDynamicNoPic:
  98. RM = Reloc::DynamicNoPIC;
  99. break;
  100. case LLVMRelocROPI:
  101. RM = Reloc::ROPI;
  102. break;
  103. case LLVMRelocRWPI:
  104. RM = Reloc::RWPI;
  105. break;
  106. case LLVMRelocROPI_RWPI:
  107. RM = Reloc::ROPI_RWPI;
  108. break;
  109. default:
  110. break;
  111. }
  112. bool JIT;
  113. Optional<CodeModel::Model> CM = unwrap(CodeModel, JIT);
  114. CodeGenOpt::Level OL;
  115. switch (Level) {
  116. case LLVMCodeGenLevelNone:
  117. OL = CodeGenOpt::None;
  118. break;
  119. case LLVMCodeGenLevelLess:
  120. OL = CodeGenOpt::Less;
  121. break;
  122. case LLVMCodeGenLevelAggressive:
  123. OL = CodeGenOpt::Aggressive;
  124. break;
  125. default:
  126. OL = CodeGenOpt::Default;
  127. break;
  128. }
  129. TargetOptions opt;
  130. return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM,
  131. OL, JIT));
  132. }
  133. void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }
  134. LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
  135. const Target* target = &(unwrap(T)->getTarget());
  136. return wrap(target);
  137. }
  138. char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
  139. std::string StringRep = unwrap(T)->getTargetTriple().str();
  140. return strdup(StringRep.c_str());
  141. }
  142. char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
  143. std::string StringRep = std::string(unwrap(T)->getTargetCPU());
  144. return strdup(StringRep.c_str());
  145. }
  146. char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
  147. std::string StringRep = std::string(unwrap(T)->getTargetFeatureString());
  148. return strdup(StringRep.c_str());
  149. }
  150. void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
  151. LLVMBool VerboseAsm) {
  152. unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
  153. }
  154. LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {
  155. return wrap(new DataLayout(unwrap(T)->createDataLayout()));
  156. }
  157. static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
  158. raw_pwrite_stream &OS,
  159. LLVMCodeGenFileType codegen,
  160. char **ErrorMessage) {
  161. TargetMachine* TM = unwrap(T);
  162. Module* Mod = unwrap(M);
  163. legacy::PassManager pass;
  164. std::string error;
  165. Mod->setDataLayout(TM->createDataLayout());
  166. CodeGenFileType ft;
  167. switch (codegen) {
  168. case LLVMAssemblyFile:
  169. ft = CGFT_AssemblyFile;
  170. break;
  171. default:
  172. ft = CGFT_ObjectFile;
  173. break;
  174. }
  175. if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) {
  176. error = "TargetMachine can't emit a file of this type";
  177. *ErrorMessage = strdup(error.c_str());
  178. return true;
  179. }
  180. pass.run(*Mod);
  181. OS.flush();
  182. return false;
  183. }
  184. LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
  185. char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
  186. std::error_code EC;
  187. raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);
  188. if (EC) {
  189. *ErrorMessage = strdup(EC.message().c_str());
  190. return true;
  191. }
  192. bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
  193. dest.flush();
  194. return Result;
  195. }
  196. LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
  197. LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
  198. LLVMMemoryBufferRef *OutMemBuf) {
  199. SmallString<0> CodeString;
  200. raw_svector_ostream OStream(CodeString);
  201. bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
  202. StringRef Data = OStream.str();
  203. *OutMemBuf =
  204. LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");
  205. return Result;
  206. }
  207. char *LLVMGetDefaultTargetTriple(void) {
  208. return strdup(sys::getDefaultTargetTriple().c_str());
  209. }
  210. char *LLVMNormalizeTargetTriple(const char* triple) {
  211. return strdup(Triple::normalize(StringRef(triple)).c_str());
  212. }
  213. char *LLVMGetHostCPUName(void) {
  214. return strdup(sys::getHostCPUName().data());
  215. }
  216. char *LLVMGetHostCPUFeatures(void) {
  217. SubtargetFeatures Features;
  218. StringMap<bool> HostFeatures;
  219. if (sys::getHostCPUFeatures(HostFeatures))
  220. for (auto &F : HostFeatures)
  221. Features.AddFeature(F.first(), F.second);
  222. return strdup(Features.getString().c_str());
  223. }
  224. void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
  225. unwrap(PM)->add(
  226. createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
  227. }