TargetMachineC.cpp 7.1 KB

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