TargetMachineC.cpp 7.6 KB

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