/src/rustllvm/RustWrapper.cpp

http://github.com/jruderman/rust · C++ · 192 lines · 150 code · 25 blank · 17 comment · 4 complexity · d7d2ca0f053d50105a03adf33c2ba2d6 MD5 · raw file

  1. //===- RustWrapper.cpp - Rust wrapper for core functions --------*- C++ -*-===
  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 defines alternate interfaces to core functions that are more
  11. // readily callable by Rust's FFI.
  12. //
  13. //===----------------------------------------------------------------------===
  14. #include "llvm/LLVMContext.h"
  15. #include "llvm/Linker.h"
  16. #include "llvm/PassManager.h"
  17. #include "llvm/ADT/Triple.h"
  18. #include "llvm/Assembly/Parser.h"
  19. #include "llvm/Assembly/PrintModulePass.h"
  20. #include "llvm/Support/FormattedStream.h"
  21. #include "llvm/Support/Timer.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. #include "llvm/Target/TargetMachine.h"
  24. #include "llvm/Support/TargetSelect.h"
  25. #include "llvm/Support/TargetRegistry.h"
  26. #include "llvm/Support/SourceMgr.h"
  27. #include "llvm/Target/TargetOptions.h"
  28. #include "llvm/Support/Host.h"
  29. #include "llvm/Support/Debug.h"
  30. #include "llvm-c/Core.h"
  31. #include "llvm-c/BitReader.h"
  32. #include "llvm-c/Object.h"
  33. #include <cstdlib>
  34. using namespace llvm;
  35. static const char *LLVMRustError;
  36. extern "C" LLVMMemoryBufferRef
  37. LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
  38. LLVMMemoryBufferRef MemBuf = NULL;
  39. LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
  40. const_cast<char **>(&LLVMRustError));
  41. return MemBuf;
  42. }
  43. extern "C" const char *LLVMRustGetLastError(void) {
  44. return LLVMRustError;
  45. }
  46. extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
  47. extern "C" void LLVMRustAddPrintModulePass(LLVMPassManagerRef PMR,
  48. LLVMModuleRef M,
  49. const char* path) {
  50. PassManager *PM = unwrap<PassManager>(PMR);
  51. std::string ErrorInfo;
  52. raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
  53. formatted_raw_ostream FOS(OS);
  54. PM->add(createPrintModulePass(&FOS));
  55. PM->run(*unwrap(M));
  56. }
  57. void LLVMInitializeX86TargetInfo();
  58. void LLVMInitializeX86Target();
  59. void LLVMInitializeX86TargetMC();
  60. void LLVMInitializeX86AsmPrinter();
  61. void LLVMInitializeX86AsmParser();
  62. extern "C" bool
  63. LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
  64. LLVMModuleRef M,
  65. const char *triple,
  66. const char *path,
  67. TargetMachine::CodeGenFileType FileType,
  68. CodeGenOpt::Level OptLevel,
  69. bool EnableSegmentedStacks) {
  70. // Only initialize the platforms supported by Rust here,
  71. // because using --llvm-root will have multiple platforms
  72. // that rustllvm doesn't actually link to and it's pointless to put target info
  73. // into the registry that Rust can not generate machine code for.
  74. LLVMInitializeX86TargetInfo();
  75. LLVMInitializeX86Target();
  76. LLVMInitializeX86TargetMC();
  77. LLVMInitializeX86AsmPrinter();
  78. LLVMInitializeX86AsmParser();
  79. TargetOptions Options;
  80. Options.NoFramePointerElim = true;
  81. Options.EnableSegmentedStacks = EnableSegmentedStacks;
  82. std::string Err;
  83. const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err);
  84. std::string FeaturesStr;
  85. std::string Trip(triple);
  86. std::string CPUStr("generic");
  87. TargetMachine *Target =
  88. TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr,
  89. Options, Reloc::PIC_,
  90. CodeModel::Default, OptLevel);
  91. bool NoVerify = false;
  92. PassManager *PM = unwrap<PassManager>(PMR);
  93. std::string ErrorInfo;
  94. raw_fd_ostream OS(path, ErrorInfo,
  95. raw_fd_ostream::F_Binary);
  96. if (ErrorInfo != "") {
  97. LLVMRustError = ErrorInfo.c_str();
  98. return false;
  99. }
  100. formatted_raw_ostream FOS(OS);
  101. bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify);
  102. assert(!foo);
  103. (void)foo;
  104. PM->run(*unwrap(M));
  105. delete Target;
  106. return true;
  107. }
  108. extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(const char *Filename) {
  109. SMDiagnostic d;
  110. Module *m = ParseAssemblyFile(Filename, d, getGlobalContext());
  111. if (m) {
  112. return wrap(m);
  113. } else {
  114. LLVMRustError = d.getMessage().c_str();
  115. return NULL;
  116. }
  117. }
  118. extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) {
  119. LLVMModuleRef M;
  120. return LLVMParseBitcode(MemBuf, &M, const_cast<char **>(&LLVMRustError))
  121. ? NULL : M;
  122. }
  123. extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
  124. LLVMBool SignExtend) {
  125. return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
  126. }
  127. extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
  128. unsigned N_hi,
  129. unsigned N_lo,
  130. LLVMBool SignExtend) {
  131. unsigned long long N = N_hi;
  132. N <<= 32;
  133. N |= N_lo;
  134. return LLVMConstInt(IntTy, N, SignExtend);
  135. }
  136. extern bool llvm::TimePassesIsEnabled;
  137. extern "C" void LLVMRustEnableTimePasses() {
  138. TimePassesIsEnabled = true;
  139. }
  140. extern "C" void LLVMRustPrintPassTimings() {
  141. raw_fd_ostream OS (2, false); // stderr.
  142. TimerGroup::printAll(OS);
  143. }
  144. extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
  145. const char* Name,
  146. LLVMTypeRef FunctionTy) {
  147. return wrap(unwrap(M)->getOrInsertFunction(Name,
  148. unwrap<FunctionType>(FunctionTy)));
  149. }
  150. extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
  151. return wrap(Type::getMetadataTy(*unwrap(C)));
  152. }
  153. extern "C" LLVMTypeRef LLVMMetadataType(void) {
  154. return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
  155. }
  156. extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
  157. AtomicRMWInst::BinOp op,
  158. LLVMValueRef target,
  159. LLVMValueRef source,
  160. AtomicOrdering order) {
  161. return wrap(unwrap(B)->CreateAtomicRMW(op,
  162. unwrap(target), unwrap(source),
  163. order));
  164. }
  165. extern "C" void LLVMSetDebug(int Enabled) {
  166. DebugFlag = Enabled;
  167. }