about summary refs log tree commit diff
path: root/src/rustllvm/RustWrapper.cpp
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-08-22 20:58:42 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-08-26 20:11:51 -0700
commit73540551e5051c524b5533a5ab3eb991dda4eaac (patch)
treed623ac8cc5a5a400e5dba821e59928fad876a079 /src/rustllvm/RustWrapper.cpp
parent6a649e6b8b3e42bb8fa8fa806d783ecd9b543784 (diff)
downloadrust-73540551e5051c524b5533a5ab3eb991dda4eaac.tar.gz
rust-73540551e5051c524b5533a5ab3eb991dda4eaac.zip
Rewrite pass management with LLVM
Beforehand, it was unclear whether rust was performing the "recommended set" of
optimizations provided by LLVM for code. This commit changes the way we run
passes to closely mirror that of clang, which in theory does it correctly. The
notable changes include:

* Passes are no longer explicitly added one by one. This would be difficult to
  keep up with as LLVM changes and we don't guaranteed always know the best
  order in which to run passes
* Passes are now managed by LLVM's PassManagerBuilder object. This is then used
  to populate the various pass managers run.
* We now run both a FunctionPassManager and a module-wide PassManager. This is
  what clang does, and I presume that we *may* see a speed boost from the
  module-wide passes just having to do less work. I have no measured this.
* The codegen pass manager has been extracted to its own separate pass manager
  to not get mixed up with the other passes
* All pass managers now include passes for target-specific data layout and
  analysis passes

Some new features include:

* You can now print all passes being run with `-Z print-llvm-passes`
* When specifying passes via `--passes`, the passes are now appended to the
  default list of passes instead of overwriting them.
* The output of `--passes list` is now generated by LLVM instead of maintaining
  a list of passes ourselves
* Loop vectorization is turned on by default as an optimization pass and can be
  disabled with `-Z no-vectorize-loops`
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
-rw-r--r--src/rustllvm/RustWrapper.cpp147
1 files changed, 4 insertions, 143 deletions
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 5b8c6bc883f..40ee486ec2d 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -20,9 +20,7 @@
 using namespace llvm;
 using namespace llvm::sys;
 
-static const char *LLVMRustError;
-
-extern cl::opt<bool> EnableARMEHABI;
+const char *LLVMRustError;
 
 extern "C" LLVMMemoryBufferRef
 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
@@ -36,62 +34,6 @@ extern "C" const char *LLVMRustGetLastError(void) {
   return LLVMRustError;
 }
 
-extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
-
-extern "C" void LLVMRustAddPrintModulePass(LLVMPassManagerRef PMR,
-                                           LLVMModuleRef M,
-                                           const char* path) {
-  PassManager *PM = unwrap<PassManager>(PMR);
-  std::string ErrorInfo;
-  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_Binary);
-  formatted_raw_ostream FOS(OS);
-  PM->add(createPrintModulePass(&FOS));
-  PM->run(*unwrap(M));
-}
-
-void LLVMInitializeX86TargetInfo();
-void LLVMInitializeX86Target();
-void LLVMInitializeX86TargetMC();
-void LLVMInitializeX86AsmPrinter();
-void LLVMInitializeX86AsmParser();
-
-
-void LLVMInitializeARMTargetInfo();
-void LLVMInitializeARMTarget();
-void LLVMInitializeARMTargetMC();
-void LLVMInitializeARMAsmPrinter();
-void LLVMInitializeARMAsmParser();
-
-void LLVMInitializeMipsTargetInfo();
-void LLVMInitializeMipsTarget();
-void LLVMInitializeMipsTargetMC();
-void LLVMInitializeMipsAsmPrinter();
-void LLVMInitializeMipsAsmParser();
-// Only initialize the platforms supported by Rust here,
-// because using --llvm-root will have multiple platforms
-// that rustllvm doesn't actually link to and it's pointless to put target info
-// into the registry that Rust can not generate machine code for.
-
-void LLVMRustInitializeTargets() {
-  LLVMInitializeX86TargetInfo();
-  LLVMInitializeX86Target();
-  LLVMInitializeX86TargetMC();
-  LLVMInitializeX86AsmPrinter();
-  LLVMInitializeX86AsmParser();
-
-  LLVMInitializeARMTargetInfo();
-  LLVMInitializeARMTarget();
-  LLVMInitializeARMTargetMC();
-  LLVMInitializeARMAsmPrinter();
-  LLVMInitializeARMAsmParser();
-
-  LLVMInitializeMipsTargetInfo();
-  LLVMInitializeMipsTarget();
-  LLVMInitializeMipsTargetMC();
-  LLVMInitializeMipsAsmPrinter();
-  LLVMInitializeMipsAsmParser();
-}
-
 // Custom memory manager for MCJITting. It needs special features
 // that the generic JIT memory manager doesn't entail. Based on
 // code from LLI, change where needed for Rust.
@@ -367,85 +309,9 @@ LLVMRustBuildJIT(void* mem,
   return wrap(EE);
 }
 
-extern "C" bool
-LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
-                        LLVMModuleRef M,
-                        const char *triple,
-                        const char *cpu,
-                        const char *feature,
-                        const char *path,
-                        TargetMachine::CodeGenFileType FileType,
-                        CodeGenOpt::Level OptLevel,
-      bool EnableSegmentedStacks) {
-
-  LLVMRustInitializeTargets();
-
-  // Initializing the command-line options more than once is not
-  // allowed. So, check if they've already been initialized.
-  // (This could happen if we're being called from rustpkg, for
-  // example.)
-  if (!EnableARMEHABI) {
-    int argc = 3;
-    const char* argv[] = {"rustc", "-arm-enable-ehabi",
-        "-arm-enable-ehabi-descriptors"};
-    cl::ParseCommandLineOptions(argc, argv);
-  }
-
-  Triple Trip(Triple::normalize(triple));
-
-  TargetOptions Options;
-  Options.EnableSegmentedStacks = EnableSegmentedStacks;
-  Options.FixedStackSegmentSize = 2 * 1024 * 1024;  // XXX: This is too big.
-  Options.FloatABIType =
-      (Trip.getEnvironment() == Triple::GNUEABIHF) ? FloatABI::Hard :
-                                                     FloatABI::Default;
-
-  PassManager *PM = unwrap<PassManager>(PMR);
-
-  std::string Err;
-  std::string FeaturesStr(feature);
-  std::string CPUStr(cpu);
-  const Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(), Err);
-  TargetMachine *Target =
-    TheTarget->createTargetMachine(Trip.getTriple(), CPUStr, FeaturesStr,
-           Options, Reloc::PIC_,
-           CodeModel::Default, OptLevel);
-  Target->addAnalysisPasses(*PM);
-
-  bool NoVerify = false;
-  std::string ErrorInfo;
-  raw_fd_ostream OS(path, ErrorInfo,
-                    sys::fs::F_Binary);
-  if (ErrorInfo != "") {
-    LLVMRustError = ErrorInfo.c_str();
-    return false;
-  }
-  formatted_raw_ostream FOS(OS);
-
-  bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify);
-  assert(!foo);
-  (void)foo;
-  PM->run(*unwrap(M));
-  delete Target;
-  return true;
-}
-
-extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(LLVMContextRef C,
-                                                   const char *Filename) {
-  SMDiagnostic d;
-  Module *m = ParseAssemblyFile(Filename, d, *unwrap(C));
-  if (m) {
-    return wrap(m);
-  } else {
-    LLVMRustError = d.getMessage().str().c_str();
-    return NULL;
-  }
-}
-
-extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) {
-  LLVMModuleRef M;
-  return LLVMParseBitcode(MemBuf, &M, const_cast<char **>(&LLVMRustError))
-         ? NULL : M;
+extern "C" void
+LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
+    unwrap(M)->setTargetTriple(Triple::normalize(triple));
 }
 
 extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
@@ -463,11 +329,6 @@ extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
   return LLVMConstInt(IntTy, N, SignExtend);
 }
 
-extern bool llvm::TimePassesIsEnabled;
-extern "C" void LLVMRustEnableTimePasses() {
-  TimePassesIsEnabled = true;
-}
-
 extern "C" void LLVMRustPrintPassTimings() {
   raw_fd_ostream OS (2, false); // stderr.
   TimerGroup::printAll(OS);