diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-08-22 20:58:42 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-08-26 20:11:51 -0700 |
| commit | 73540551e5051c524b5533a5ab3eb991dda4eaac (patch) | |
| tree | d623ac8cc5a5a400e5dba821e59928fad876a079 /src/rustllvm/RustWrapper.cpp | |
| parent | 6a649e6b8b3e42bb8fa8fa806d783ecd9b543784 (diff) | |
| download | rust-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.cpp | 147 |
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); |
