about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_llvm/lib.rs14
-rw-r--r--src/librustc_trans/back/lto.rs8
-rw-r--r--src/librustc_trans/back/write.rs19
-rw-r--r--src/rustllvm/PassWrapper.cpp36
4 files changed, 65 insertions, 12 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index fc7fa299fb8..0f85c4528d2 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -461,6 +461,15 @@ pub enum ArchiveKind {
     K_COFF,
 }
 
+/// Represents the different LLVM passes Rust supports
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(C)]
+pub enum SupportedPassKind {
+    Function,
+    Module,
+    Unsupported,
+}
+
 // Opaque pointer types
 #[allow(missing_copy_implementations)]
 pub enum Module_opaque {}
@@ -2008,7 +2017,10 @@ extern {
     pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
     pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
 
-    pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
+    pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
+    pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
+    pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
+
     pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
                                        CPU: *const c_char,
                                        Features: *const c_char,
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index 85419a07250..06d32b8f601 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -145,7 +145,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
     unsafe {
         let pm = llvm::LLVMCreatePassManager();
         llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
-        llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
+        let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+        assert!(!pass.is_null());
+        llvm::LLVMRustAddPass(pm, pass);
 
         with_llvm_pmb(llmod, config, &mut |b| {
             llvm::LLVMPassManagerBuilderPopulateLTOPassManager(b, pm,
@@ -153,7 +155,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                 /* RunInliner = */ True);
         });
 
-        llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
+        let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+        assert!(!pass.is_null());
+        llvm::LLVMRustAddPass(pm, pass);
 
         time(sess.time_passes(), "LTO passes", ||
              llvm::LLVMRunPassManager(pm, llmod));
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 544df1798ea..bc007da7174 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -446,9 +446,22 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
 
         // If we're verifying or linting, add them to the function pass
         // manager.
-        let addpass = |pass: &str| {
-            let pass = CString::new(pass).unwrap();
-            llvm::LLVMRustAddPass(fpm, pass.as_ptr())
+        let addpass = |pass_name: &str| {
+            let pass_name = CString::new(pass_name).unwrap();
+            let pass = llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr());
+            if pass.is_null() {
+                return false;
+            }
+            let pass_manager = match llvm::LLVMRustPassKind(pass) {
+                llvm::SupportedPassKind::Function => fpm,
+                llvm::SupportedPassKind::Module => mpm,
+                llvm::SupportedPassKind::Unsupported => {
+                    cgcx.handler.err("Encountered LLVM pass kind we can't handle");
+                    return true
+                },
+            };
+            llvm::LLVMRustAddPass(pass_manager, pass);
+            true
         };
 
         if !config.no_verify { assert!(addpass("verify")); }
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 30096677aa4..d6985719acb 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -58,19 +58,43 @@ LLVMInitializePasses() {
   initializeTarget(Registry);
 }
 
-extern "C" bool
-LLVMRustAddPass(LLVMPassManagerRef PM, const char *PassName) {
-    PassManagerBase *pm = unwrap(PM);
 
+enum class SupportedPassKind {
+  Function,
+  Module,
+  Unsupported
+};
+
+extern "C" Pass*
+LLVMRustFindAndCreatePass(const char *PassName) {
     StringRef SR(PassName);
     PassRegistry *PR = PassRegistry::getPassRegistry();
 
     const PassInfo *PI = PR->getPassInfo(SR);
     if (PI) {
-        pm->add(PI->createPass());
-        return true;
+        return PI->createPass();
     }
-    return false;
+    return NULL;
+}
+
+extern "C" SupportedPassKind
+LLVMRustPassKind(Pass *pass) {
+    assert(pass);
+    PassKind passKind = pass->getPassKind();
+    if (passKind == PT_Module) {
+        return SupportedPassKind::Module;
+    } else if (passKind == PT_Function) {
+        return SupportedPassKind::Function;
+    } else {
+        return SupportedPassKind::Unsupported;
+    }
+}
+
+extern "C" void
+LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
+    assert(pass);
+    PassManagerBase *pm = unwrap(PM);
+    pm->add(pass);
 }
 
 extern "C" LLVMTargetMachineRef