about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-29 16:58:44 -0700
committerbors <bors@rust-lang.org>2013-05-29 16:58:44 -0700
commitb5da389d36ec9108f82bb7025eabb7ce4f26b103 (patch)
tree514f7b5aeaaaafc627eb415bca7b6667bbad1f12
parentbd30285c8467b33b6fea16be79198f7492107af3 (diff)
parentfaf1afee16cfacf0318ca2b88bc4fa5e507418dd (diff)
downloadrust-b5da389d36ec9108f82bb7025eabb7ce4f26b103.tar.gz
rust-b5da389d36ec9108f82bb7025eabb7ce4f26b103.zip
auto merge of #6799 : Aatch/rust/pass-refactor, r=graydon
This refactors pass handling to use the argument names, so it can be used
in a similar manner to `opt`. This may be slightly less efficient than the
previous version, but it is much easier to maintain.

It also adds in the ability to specify a custom pipeline on the command
line, this overrides the normal passes, however. This should completely
close #2396.
-rw-r--r--src/librustc/back/link.rs19
-rw-r--r--src/librustc/back/passes.rs332
-rw-r--r--src/librustc/driver/driver.rs16
-rw-r--r--src/librustc/driver/session.rs2
-rw-r--r--src/librustc/lib/llvm.rs202
-rw-r--r--src/librustc/rustc.rc5
-rw-r--r--src/rustllvm/PassWrapper.cpp141
-rw-r--r--src/rustllvm/rustllvm.def.in100
8 files changed, 321 insertions, 496 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index 51d60437868..c3847ee4f15 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -202,6 +202,8 @@ pub mod write {
                       output_type: output_type,
                       output: &Path) {
         unsafe {
+            llvm::LLVMInitializePasses();
+
             let opts = sess.opts;
             if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
             let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);
@@ -232,14 +234,21 @@ pub mod write {
             let mut mpm = passes::PassManager::new(td.lltd);
 
             if !sess.no_verify() {
-                mpm.addPass(llvm::LLVMCreateVerifierPass());
+                mpm.add_pass_from_name("verify");
             }
 
-            if sess.lint_llvm() {
-                mpm.addPass(llvm::LLVMCreateLintPass());
-            }
+            let passes = if sess.opts.custom_passes.len() > 0 {
+                copy sess.opts.custom_passes
+            } else {
+                if sess.lint_llvm() {
+                    mpm.add_pass_from_name("lint");
+                }
+                passes::create_standard_passes(opts.optimize)
+            };
+
 
-            passes::populatePassManager(&mut mpm, opts.optimize);
+            debug!("Passes: %?", passes);
+            passes::populate_pass_manager(sess, &mut mpm, passes);
 
             debug!("Running Module Optimization Pass");
             mpm.run(llmod);
diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs
index ba4170fde56..2e304b93c7e 100644
--- a/src/librustc/back/passes.rs
+++ b/src/librustc/back/passes.rs
@@ -10,7 +10,8 @@
 
 use core::prelude::*;
 
-use driver::session;
+use driver::session::{OptLevel, No, Less, Default, Aggressive};
+use driver::session::{Session};
 use lib::llvm::{PassRef, ModuleRef,PassManagerRef,TargetDataRef};
 use lib::llvm::llvm;
 use lib;
@@ -39,12 +40,17 @@ impl PassManager {
         }
     }
 
-    pub fn addPass(&mut self, pass:PassRef) {
+    pub fn add_pass(&mut self, pass:PassRef) {
         unsafe {
             llvm::LLVMAddPass(self.llpm, pass);
         }
     }
 
+    pub fn add_pass_from_name(&mut self, name:&str) {
+        let pass = create_pass(name).unwrap();
+        self.add_pass(pass);
+    }
+
     pub fn run(&self, md:ModuleRef) -> bool {
         unsafe {
             llvm::LLVMRunPassManager(self.llpm, md) == lib::llvm::True
@@ -52,103 +58,271 @@ impl PassManager {
     }
 }
 
+pub fn create_standard_passes(level:OptLevel) -> ~[~str] {
+    let mut passes = ~[~"strip-dead-prototypes"];
 
-pub fn populatePassManager(pm: &mut PassManager, level:session::OptLevel) {
-    unsafe {
-        // We add a lot of normally-unused prototypes, so always strip them
-        // straight away, later passes will get rid of any that are optimized
-        // away
-        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());
-        if level == session::No {
-            pm.addPass(llvm::LLVMCreateAlwaysInlinerPass());
+    if level == No {
+        passes.push(~"always-inline");
+        return passes;
+    }
 
-            return;
-        }
+    passes.push(~"targetlibinfo");
 
-        //NOTE: Add library info
+    passes.push(~"tbaa");
+    passes.push(~"basicaa");
 
-        pm.addPass(llvm::LLVMCreateTypeBasedAliasAnalysisPass());
-        pm.addPass(llvm::LLVMCreateBasicAliasAnalysisPass());
+    passes.push(~"early-cse");
 
-        pm.addPass(llvm::LLVMCreateSROAPass());
-        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
-        pm.addPass(llvm::LLVMCreateLowerExpectIntrinsicPass());
+    passes.push(~"globalopt");
+    passes.push(~"ipsccp");
+    passes.push(~"deadargelim");
+    passes.push(~"instcombine");
+    passes.push(~"simplifycfg");
 
-        pm.addPass(llvm::LLVMCreateGlobalOptimizerPass());
-        pm.addPass(llvm::LLVMCreateIPSCCPPass());
-        pm.addPass(llvm::LLVMCreateDeadArgEliminationPass());
-        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
-        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
+    passes.push(~"prune-eh");
 
-        pm.addPass(llvm::LLVMCreatePruneEHPass());
+    if level == Aggressive {
+        passes.push(~"mergefunc");
+    }
 
-        if level == session::Aggressive {
-            // Do this before inlining, since inlining might
-            // make minor changes to functions that mean they
-            // can't be merged, despite being almost identical
-            pm.addPass(llvm::LLVMCreateMergeFunctionsPass());
-        }
+    passes.push(~"inline");
 
-        match level {
-            session::Less       => pm.addPass(llvm::LLVMCreateFunctionInliningPass(200)),
-            session::Default    => pm.addPass(llvm::LLVMCreateFunctionInliningPass(225)),
-            session::Aggressive => pm.addPass(llvm::LLVMCreateFunctionInliningPass(275)),
-            session::No         => ()
-        }
+    passes.push(~"functionattrs");
 
-        pm.addPass(llvm::LLVMCreateFunctionAttrsPass());
+    if level == Aggressive {
+        passes.push(~"argpromotion");
+    }
 
-        if level == session::Aggressive {
-            pm.addPass(llvm::LLVMCreateArgumentPromotionPass());
-        }
+    passes.push(~"early-cse");
+    passes.push(~"simplify-libcalls");
+    passes.push(~"jump-threading");
+    passes.push(~"correlated-propagation");
+    passes.push(~"simplifycfg");
+    passes.push(~"instcombine");
+
+    passes.push(~"tailcallelim");
+    passes.push(~"simplifycfg");
+    passes.push(~"reassociate");
+    passes.push(~"loop-rotate");
+    passes.push(~"licm");
+
+    passes.push(~"lcssa");
+    passes.push(~"loop-unswitch");
+
+    passes.push(~"instcombine");
+    passes.push(~"indvars");
+    passes.push(~"loop-idiom");
+    passes.push(~"loop-deletion");
+
+    if level == Aggressive {
+        passes.push(~"loop-vectorize");
+    }
+
+    passes.push(~"loop-unroll");
+
+    if level != Less {
+        passes.push(~"gvn");
+    }
+
+    passes.push(~"memcpyopt");
+    passes.push(~"sccp");
+
+    passes.push(~"instcombine");
+    passes.push(~"jump-threading");
+    passes.push(~"correlated-propagation");
+    passes.push(~"dse");
+
+    passes.push(~"bb-vectorize");
+    passes.push(~"instcombine");
+    passes.push(~"early-cse");
+
+    passes.push(~"loop-unroll");
+
+    passes.push(~"adce");
+    passes.push(~"simplifycfg");
+    passes.push(~"instsimplify");
 
-        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
-        pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass());
-        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
-        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
-        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
-        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
-
-        pm.addPass(llvm::LLVMCreateTailCallEliminationPass());
-        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
-        pm.addPass(llvm::LLVMCreateReassociatePass());
-        pm.addPass(llvm::LLVMCreateLoopRotatePass());
-        pm.addPass(llvm::LLVMCreateLICMPass());
-
-        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
-        pm.addPass(llvm::LLVMCreateIndVarSimplifyPass());
-        pm.addPass(llvm::LLVMCreateLoopIdiomPass());
-        pm.addPass(llvm::LLVMCreateLoopDeletionPass());
-
-        if level == session::Aggressive {
-            pm.addPass(llvm::LLVMCreateLoopVectorizePass());
+    if level != Less {
+        passes.push(~"globaldce");
+        passes.push(~"constmerge");
+    }
+
+    return passes;
+}
+
+pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~str]) {
+    for pass_list.each |&nm| {
+        match create_pass(nm) {
+            Some(p) => pm.add_pass(p),
+            None    => sess.warn(fmt!("Unknown pass %s", nm))
         }
-        pm.addPass(llvm::LLVMCreateLoopUnrollPass());
+    }
+}
 
-        if level != session::Less {
-            pm.addPass(llvm::LLVMCreateGVNPass());
+pub fn create_pass(name:&str) -> Option<PassRef> {
+    do str::as_c_str(name) |s| {
+        unsafe {
+            let p = llvm::LLVMCreatePass(s);
+            if p.is_null() {
+                None
+            } else {
+                Some(p)
+            }
         }
-        pm.addPass(llvm::LLVMCreateMemCpyOptPass());
-        pm.addPass(llvm::LLVMCreateSCCPPass());
+    }
+}
 
-        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
-        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
-        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
-        pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());
+pub fn list_passes() {
+    io::println("\nAvailable Passes:");
 
-        pm.addPass(llvm::LLVMCreateBBVectorizePass());
-        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
-        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
+    io::println("\nAnalysis Passes:");
+    for analysis_passes.each |&(name, desc)| {
+        io::println(fmt!("    %-30s -- %s", name, desc));
+    }
+    io::println("\nTransformation Passes:");
+    for transform_passes.each |&(name, desc)| {
+        io::println(fmt!("    %-30s -- %s", name, desc));
+    }
+    io::println("\nUtility Passes:");
+    for utility_passes.each |&(name, desc)| {
+        io::println(fmt!("    %-30s -- %s", name, desc));
+    }
+}
+
+/** Analysis Passes */
+pub static analysis_passes : &'static [(&'static str, &'static str)] = &'static [
+    ("aa-eval",                         "Exhausive Alias Analysis Precision Evaluator"),
+    ("asan",                            "AddressSanitizer"),
+    ("basicaa",                         "Basic Alias Analysis"),
+    ("basiccg",                         "Basic CallGraph Construction"),
+    ("block-freq",                      "Block Frequency Analysis"),
+    ("cost-model",                      "Cost Model Analysis"),
+    ("count-aa",                        "Count Alias Analysis Query Responses"),
+    ("da",                              "Dependence Analysis"),
+    ("debug-aa",                        "AA Use Debugger"),
+    ("domfrontier",                     "Dominance Frontier Construction"),
+    ("domtree",                         "Dominator Tree Construction"),
+    ("globalsmodref-aa",                "Simple mod/ref analysis for globals"),
+    ("instcount",                       "Count the various types of Instructions"),
+    ("intervals",                       "Interval Partition Construction"),
+    ("iv-users",                        "Induction Variable Users"),
+    ("lazy-value-info",                 "Lazy Value Information Analysis"),
+    ("libcall-aa",                      "LibCall Alias Analysis"),
+    ("lint",                            "Statically lint-check LLVM IR"),
+    ("loops",                           "Natural Loop Information"),
+    ("memdep",                          "Memory Dependence Analysis"),
+    ("module-debuginfo",                "Decodes module-level debug info"),
+    ("profile-estimator",               "Estimate profiling information"),
+    ("profile-loader",                  "Load profile information from llvmprof.out"),
+    ("profile-verifier",                "Verify profiling information"),
+    ("regions",                         "Detect single entry single exit regions"),
+    ("scalar-evolution",                "Scalar Evolution Analysis"),
+    ("scev-aa",                         "Scalar Evolution-based Alias Analysis"),
+    ("tbaa",                            "Type-Based Alias Analysis"),
+    ("tsan",                            "ThreadSanitizer"),
+];
 
-        pm.addPass(llvm::LLVMCreateLoopUnrollPass());
+/** Transformation Passes */
+pub static transform_passes : &'static [(&'static str, &'static str)] = &'static [
+    ("adce",                            "Aggressive Dead Code Elimination"),
+    ("always-inline",                   "Inliner for #[inline(always)] functions"),
+    ("argpromotion",                    "Promote 'by reference' arguments to scalars"),
+    ("bb-vectorize",                    "Basic-Block Vectorization"),
+    ("block-placement",                 "Profile Guided Basic Block Placement"),
+    ("bounds-checking",                 "Run-time bounds checking"),
+    ("break-crit-edges",                "Break critical edges in CFG"),
+    ("codegenprepare",                  "Optimize for code generation"),
+    ("constmerge",                      "Merge Duplicate Global Constants"),
+    ("constprop",                       "Simple constant propagation"),
+    ("correlated-propagation",          "Value Propagation"),
+    ("da",                              "Data Layout"),
+    ("dce",                             "Dead Code Elimination"),
+    ("deadargelim",                     "Dead Argument Elimination"),
+    ("die",                             "Dead Instruction Elimination"),
+    ("dse",                             "Dead Store Elimination"),
+    ("early-cse",                       "Early CSE"),
+    ("functionattrs",                   "Deduce function attributes"),
+    ("globaldce",                       "Dead Global Elimination"),
+    ("globalopt",                       "Global Variable Optimizer"),
+    ("gvn",                             "Global Value Numbering"),
+    ("indvars",                         "Canonicalize Induction Variables"),
+    ("inline",                          "Function Integration/Inlining"),
+    ("insert-edge-profiling",           "Insert instrumentation for edge profiling"),
+    ("insert-gcov-profiling",           "Insert instrumentation for GCOV profiling"),
+    ("insert-optimal-edge-profiling",   "Insert optimal instrumentation for edge profiling"),
+    ("instcombine",                     "Combine redundant instructions"),
+    ("instsimplify",                    "Remove redundant instructions"),
+    ("ipconstprop",                     "Interprocedural constant propagation"),
+    ("ipsccp",                          "Interprocedural Sparse Conditional Constant Propagation"),
+    ("jump-threading",                  "Jump Threading"),
+    ("lcssa",                           "Loop-Closed SSA Form Pass"),
+    ("licm",                            "Loop Invariant Code Motion"),
+    ("loop-deletion",                   "Delete dead loops"),
+    ("loop-extract",                    "Extract loops into new functions"),
+    ("loop-extract-single",             "Extract at most one loop into a new function"),
+    ("loop-idiom",                      "Recognise loop idioms"),
+    ("loop-instsimplify",               "Simplify instructions in loops"),
+    ("loop-reduce",                     "Loop Strength Reduction"),
+    ("loop-rotate",                     "Rotate Loops"),
+    ("loop-simplify",                   "Canonicalize natural loops"),
+    ("loop-unroll",                     "Unroll loops"),
+    ("loop-unswitch",                   "Unswitch loops"),
+    ("loop-vectorize",                  "Loop Vectorization"),
+    ("lower-expect",                    "Lower 'expect' Intrinsics"),
+    ("mem2reg",                         "Promote Memory to Register"),
+    ("memcpyopt",                       "MemCpy Optimization"),
+    ("mergefunc",                       "Merge Functions"),
+    ("mergereturn",                     "Unify function exit nodes"),
+    ("partial-inliner",                 "Partial Inliner"),
+    ("prune-eh",                        "Remove unused exception handling info"),
+    ("reassociate",                     "Reassociate expressions"),
+    ("reg2mem",                         "Demote all values to stack slots"),
+    ("scalarrepl",                      "Scalar Replacement of Aggregates (DT)"),
+    ("scalarrepl-ssa",                  "Scalar Replacement of Aggregates (SSAUp)"),
+    ("sccp",                            "Sparse Conditional Constant Propagation"),
+    ("simplify-libcalls",               "Simplify well-known library calls"),
+    ("simplifycfg",                     "Simplify the CFG"),
+    ("sink",                            "Code sinking"),
+    ("strip",                           "Strip all symbols from a module"),
+    ("strip-dead-debug-info",           "Strip debug info for unused symbols"),
+    ("strip-dead-prototypes",           "Strip Unused Function Prototypes"),
+    ("strip-debug-declare",             "Strip all llvm.dbg.declare intrinsics"),
+    ("strip-nondebug",                  "Strip all symbols, except dbg symbols, from a module"),
+    ("sroa",                            "Scalar Replacement of Aggregates"),
+    ("tailcallelim",                    "Tail Call Elimination"),
+];
 
-        pm.addPass(llvm::LLVMCreateAggressiveDCEPass());
-        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
-        pm.addPass(llvm::LLVMCreateInstructionSimplifierPass());
+/** Utility Passes */
+static utility_passes : &'static [(&'static str, &'static str)] = &'static [
+    ("instnamer",                       "Assign names to anonymous instructions"),
+    ("verify",                          "Module Verifier"),
+];
+
+#[test]
+fn passes_exist() {
+    let mut failed = ~[];
+    unsafe { llvm::LLVMInitializePasses(); }
+    for analysis_passes.each() |&(name,_)| {
+        if !create_pass(name).is_some() {
+            failed.push(name);
+        }
+    }
+    for transform_passes.each() |&(name,_)| {
+        if !create_pass(name).is_some() {
+            failed.push(name);
+        }
+    }
+    for utility_passes.each() |&(name,_)| {
+        if !create_pass(name).is_some() {
+            failed.push(name);
+        }
+    }
 
-        if level != session::Less {
-            pm.addPass(llvm::LLVMCreateGlobalDCEPass());
-            pm.addPass(llvm::LLVMCreateConstantMergePass());
+    if failed.len() > 0 {
+        io::println("Some passes don't exist:");
+        for failed.each |&n| {
+            io::println(fmt!("    %s", n));
         }
+        fail!();
     }
 }
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index a210234adb1..2d2170278ad 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -679,11 +679,24 @@ pub fn build_session_options(binary: @~str,
     let android_cross_path = getopts::opt_maybe_str(
         matches, "android-cross-path");
 
+    let custom_passes = match getopts::opt_maybe_str(matches, "passes") {
+        None => ~[],
+        Some(s) => {
+            let mut o = ~[];
+            for s.each_split(|c| c == ' ' || c == ',') |s| {
+                let s = s.trim().to_owned();
+                o.push(s);
+            }
+            o
+        }
+    };
+
     let sopts = @session::options {
         crate_type: crate_type,
         is_static: statik,
         gc: gc,
         optimize: opt_level,
+        custom_passes: custom_passes,
         debuginfo: debuginfo,
         extra_debuginfo: extra_debuginfo,
         lint_opts: lint_opts,
@@ -785,6 +798,9 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
   optopt("o", "",     "Write output to <filename>", "FILENAME"),
   optopt("", "opt-level",
                         "Optimize with possible levels 0-3", "LEVEL"),
+  optopt("", "passes", "Comma or space separated list of pass names to use. \
+                        Overrides the default passes for optimization levels,\n\
+                        a value of \"list\" will list the available passes.", "NAMES"),
   optopt( "",  "out-dir",
                         "Write output to compiler-chosen filename
                           in <dir>", "DIR"),
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 3f2467948a2..25c860ab2f0 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -129,6 +129,7 @@ pub struct options {
     is_static: bool,
     gc: bool,
     optimize: OptLevel,
+    custom_passes: ~[~str],
     debuginfo: bool,
     extra_debuginfo: bool,
     lint_opts: ~[(lint::lint, lint::level)],
@@ -304,6 +305,7 @@ pub fn basic_options() -> @options {
         is_static: false,
         gc: false,
         optimize: No,
+        custom_passes: ~[],
         debuginfo: false,
         extra_debuginfo: false,
         lint_opts: ~[],
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index fc655ed1370..a12a8be3b11 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -1682,8 +1682,14 @@ pub mod llvm {
         pub unsafe fn LLVMFinalizeFunctionPassManager(FPM:PassManagerRef) -> Bool;
 
         #[fast_ffi]
+        pub unsafe fn LLVMInitializePasses();
+
+        #[fast_ffi]
         pub unsafe fn LLVMAddPass(PM:PassManagerRef,P:PassRef);
 
+        #[fast_ffi]
+        pub unsafe fn LLVMCreatePass(PassName:*c_char) -> PassRef;
+
         /** Adds a verification pass. */
         #[fast_ffi]
         pub unsafe fn LLVMAddVerifierPass(PM: PassManagerRef);
@@ -1926,202 +1932,6 @@ pub mod llvm {
                                     AlignStack: Bool, Dialect: c_uint)
                                  -> ValueRef;
 
-        // LLVM Passes
-
-        #[fast_ffi]
-        pub fn LLVMCreateStripSymbolsPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateStripNonDebugSymbolsPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateStripDebugDeclarePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateStripDeadDebugInfoPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateConstantMergePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGlobalOptimizerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGlobalDCEPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateAlwaysInlinerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePruneEHPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateInternalizePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDeadArgEliminationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDeadArgHackingPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateArgumentPromotionPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateIPConstantPropagationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateIPSCCPPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopExtractorPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateSingleLoopExtractorPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBlockExtractorPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateStripDeadPrototypesPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateFunctionAttrsPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateMergeFunctionsPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePartialInliningPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateMetaRenamerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBarrierNoopPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateFunctionInliningPass(Threshold:c_int) -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateEdgeProfilerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateOptimalEdgeProfilerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePathProfilerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGCOVProfilerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBoundsCheckingPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateConstantPropagationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateSCCPPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDeadInstEliminationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDeadCodeEliminationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDeadStoreEliminationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateAggressiveDCEPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateSROAPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateScalarReplAggregatesPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateIndVarSimplifyPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateInstructionCombiningPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLICMPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopStrengthReducePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGlobalMergePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopUnswitchPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopInstSimplifyPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopUnrollPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopRotatePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopIdiomPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePromoteMemoryToRegisterPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDemoteRegisterToMemoryPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateReassociatePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateJumpThreadingPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateCFGSimplificationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBreakCriticalEdgesPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopSimplifyPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateTailCallEliminationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLowerSwitchPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLowerInvokePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBlockPlacementPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLCSSAPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateEarlyCSEPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGVNPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateMemCpyOptPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopDeletionPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateSimplifyLibCallsPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateCodeGenPreparePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateInstructionNamerPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateSinkingPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLowerAtomicPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateCorrelatedValuePropagationPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateInstructionSimplifierPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLowerExpectIntrinsicPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBBVectorizePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLoopVectorizePass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateGlobalsModRefPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateAliasAnalysisCounterPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateAAEvalPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateNoAAPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateBasicAliasAnalysisPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateScalarEvolutionAliasAnalysisPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateTypeBasedAliasAnalysisPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateProfileLoaderPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateProfileMetadataLoaderPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateNoProfileInfoPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateProfileEstimatorPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateProfileVerifierPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePathProfileLoaderPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateNoPathProfileInfoPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreatePathProfileVerifierPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLazyValueInfoPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateDependenceAnalysisPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateCostModelAnalysisPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateInstCountPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateRegionInfoPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateModuleDebugInfoPrinterPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateLintPass() -> PassRef;
-        #[fast_ffi]
-        pub fn LLVMCreateVerifierPass() -> PassRef;
     }
 }
 
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index cca194a7773..bdab72c4d73 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -246,6 +246,11 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
         return;
     }
 
+    if getopts::opt_maybe_str(matches, "passes") == Some(~"list") {
+        back::passes::list_passes();
+        return;
+    }
+
     if opt_present(matches, "v") || opt_present(matches, "version") {
         version(*binary);
         return;
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index fd17dfb4cf8..53b291ff470 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -30,10 +30,20 @@ inline T *unwrap(LLVMPassRef P) {
     return Q;
 }
 
-#define WRAP_PASS(name)                             \
-    extern "C" LLVMPassRef LLVMCreate##name##Pass() {      \
-        return wrap(llvm::create##name##Pass());    \
-    }
+extern "C" void LLVMInitializePasses() {
+  PassRegistry &Registry = *PassRegistry::getPassRegistry();
+  initializeCore(Registry);
+  initializeCodeGen(Registry);
+  initializeScalarOpts(Registry);
+  initializeVectorization(Registry);
+  initializeIPO(Registry);
+  initializeAnalysis(Registry);
+  initializeIPA(Registry);
+  initializeTransformUtils(Registry);
+  initializeInstCombine(Registry);
+  initializeInstrumentation(Registry);
+  initializeTarget(Registry);
+}
 
 extern "C" void LLVMAddPass(LLVMPassManagerRef PM, LLVMPassRef P) {
     PassManagerBase * pm = unwrap(PM);
@@ -42,119 +52,14 @@ extern "C" void LLVMAddPass(LLVMPassManagerRef PM, LLVMPassRef P) {
     pm->add(p);
 }
 
-////////////////
-// Transforms //
-// /////////////
-
-// IPO Passes
-WRAP_PASS(StripSymbols)
-WRAP_PASS(StripNonDebugSymbols)
-WRAP_PASS(StripDebugDeclare)
-WRAP_PASS(StripDeadDebugInfo)
-WRAP_PASS(ConstantMerge)
-WRAP_PASS(GlobalOptimizer)
-WRAP_PASS(GlobalDCE)
-WRAP_PASS(AlwaysInliner)
-WRAP_PASS(PruneEH)
-WRAP_PASS(Internalize)
-WRAP_PASS(DeadArgElimination)
-WRAP_PASS(DeadArgHacking)
-WRAP_PASS(ArgumentPromotion)
-WRAP_PASS(IPConstantPropagation)
-WRAP_PASS(IPSCCP)
-WRAP_PASS(LoopExtractor)
-WRAP_PASS(SingleLoopExtractor)
-WRAP_PASS(BlockExtractor)
-WRAP_PASS(StripDeadPrototypes)
-WRAP_PASS(FunctionAttrs)
-WRAP_PASS(MergeFunctions)
-WRAP_PASS(PartialInlining)
-WRAP_PASS(MetaRenamer)
-WRAP_PASS(BarrierNoop)
+extern "C" LLVMPassRef LLVMCreatePass(const char * PassName) {
+    StringRef SR(PassName);
+    PassRegistry * PR = PassRegistry::getPassRegistry();
 
-extern "C" LLVMPassRef LLVMCreateFunctionInliningPass(int Threshold) {
-    return wrap(llvm::createFunctionInliningPass(Threshold));
+    const PassInfo * PI = PR->getPassInfo(SR);
+    if (PI) {
+        return wrap(PI->createPass());
+    } else {
+        return (LLVMPassRef)0;
+    }
 }
-
-// Instrumentation Passes
-WRAP_PASS(EdgeProfiler)
-WRAP_PASS(OptimalEdgeProfiler)
-WRAP_PASS(PathProfiler)
-WRAP_PASS(GCOVProfiler)
-WRAP_PASS(BoundsChecking)
-
-// Scalar Passes
-WRAP_PASS(ConstantPropagation)
-WRAP_PASS(SCCP)
-WRAP_PASS(DeadInstElimination)
-WRAP_PASS(DeadCodeElimination)
-WRAP_PASS(DeadStoreElimination)
-WRAP_PASS(AggressiveDCE)
-WRAP_PASS(SROA)
-WRAP_PASS(ScalarReplAggregates)
-WRAP_PASS(IndVarSimplify)
-WRAP_PASS(InstructionCombining)
-WRAP_PASS(LICM)
-WRAP_PASS(LoopStrengthReduce)
-WRAP_PASS(GlobalMerge)
-WRAP_PASS(LoopUnswitch)
-WRAP_PASS(LoopInstSimplify)
-WRAP_PASS(LoopUnroll)
-WRAP_PASS(LoopRotate)
-WRAP_PASS(LoopIdiom)
-WRAP_PASS(PromoteMemoryToRegister)
-WRAP_PASS(DemoteRegisterToMemory)
-WRAP_PASS(Reassociate)
-WRAP_PASS(JumpThreading)
-WRAP_PASS(CFGSimplification)
-WRAP_PASS(BreakCriticalEdges)
-WRAP_PASS(LoopSimplify)
-WRAP_PASS(TailCallElimination)
-WRAP_PASS(LowerSwitch)
-WRAP_PASS(LowerInvoke)
-WRAP_PASS(BlockPlacement)
-WRAP_PASS(LCSSA)
-WRAP_PASS(EarlyCSE)
-WRAP_PASS(GVN)
-WRAP_PASS(MemCpyOpt)
-WRAP_PASS(LoopDeletion)
-WRAP_PASS(SimplifyLibCalls)
-WRAP_PASS(CodeGenPrepare)
-WRAP_PASS(InstructionNamer)
-WRAP_PASS(Sinking)
-WRAP_PASS(LowerAtomic)
-WRAP_PASS(CorrelatedValuePropagation)
-WRAP_PASS(InstructionSimplifier)
-WRAP_PASS(LowerExpectIntrinsic)
-
-// Vectorize Passes
-WRAP_PASS(BBVectorize)
-WRAP_PASS(LoopVectorize)
-
-//////////////
-// Analyses //
-//////////////
-
-WRAP_PASS(GlobalsModRef)
-WRAP_PASS(AliasAnalysisCounter)
-WRAP_PASS(AAEval)
-WRAP_PASS(NoAA)
-WRAP_PASS(BasicAliasAnalysis)
-WRAP_PASS(ScalarEvolutionAliasAnalysis)
-WRAP_PASS(TypeBasedAliasAnalysis)
-WRAP_PASS(ProfileLoader)
-WRAP_PASS(ProfileMetadataLoader)
-WRAP_PASS(NoProfileInfo)
-WRAP_PASS(ProfileEstimator)
-WRAP_PASS(ProfileVerifier)
-WRAP_PASS(PathProfileLoader)
-WRAP_PASS(NoPathProfileInfo)
-WRAP_PASS(PathProfileVerifier)
-WRAP_PASS(LazyValueInfo)
-WRAP_PASS(DependenceAnalysis)
-WRAP_PASS(CostModelAnalysis)
-WRAP_PASS(InstCount)
-WRAP_PASS(RegionInfo)
-WRAP_PASS(ModuleDebugInfoPrinter)
-WRAP_PASS(Lint)
-WRAP_PASS(Verifier)
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index 1e1c07fd99c..8ebdbd0f307 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -584,102 +584,6 @@ LLVMConstNamedStruct
 LLVMStructCreateNamed
 LLVMStructSetBody
 LLVMInlineAsm
+LLVMInitializePasses
 LLVMAddPass
-
-LLVMCreateStripSymbolsPass
-LLVMCreateStripNonDebugSymbolsPass
-LLVMCreateStripDebugDeclarePass
-LLVMCreateStripDeadDebugInfoPass
-LLVMCreateConstantMergePass
-LLVMCreateGlobalOptimizerPass
-LLVMCreateGlobalDCEPass
-LLVMCreateAlwaysInlinerPass
-LLVMCreatePruneEHPass
-LLVMCreateInternalizePass
-LLVMCreateDeadArgEliminationPass
-LLVMCreateDeadArgHackingPass
-LLVMCreateArgumentPromotionPass
-LLVMCreateIPConstantPropagationPass
-LLVMCreateIPSCCPPass
-LLVMCreateLoopExtractorPass
-LLVMCreateSingleLoopExtractorPass
-LLVMCreateBlockExtractorPass
-LLVMCreateStripDeadPrototypesPass
-LLVMCreateFunctionAttrsPass
-LLVMCreateMergeFunctionsPass
-LLVMCreatePartialInliningPass
-LLVMCreateMetaRenamerPass
-LLVMCreateBarrierNoopPass
-LLVMCreateFunctionInliningPass
-LLVMCreateEdgeProfilerPass
-LLVMCreateOptimalEdgeProfilerPass
-LLVMCreatePathProfilerPass
-LLVMCreateGCOVProfilerPass
-LLVMCreateBoundsCheckingPass
-LLVMCreateConstantPropagationPass
-LLVMCreateSCCPPass
-LLVMCreateDeadInstEliminationPass
-LLVMCreateDeadCodeEliminationPass
-LLVMCreateDeadStoreEliminationPass
-LLVMCreateAggressiveDCEPass
-LLVMCreateSROAPass
-LLVMCreateScalarReplAggregatesPass
-LLVMCreateIndVarSimplifyPass
-LLVMCreateInstructionCombiningPass
-LLVMCreateLICMPass
-LLVMCreateLoopStrengthReducePass
-LLVMCreateGlobalMergePass
-LLVMCreateLoopUnswitchPass
-LLVMCreateLoopInstSimplifyPass
-LLVMCreateLoopUnrollPass
-LLVMCreateLoopRotatePass
-LLVMCreateLoopIdiomPass
-LLVMCreatePromoteMemoryToRegisterPass
-LLVMCreateDemoteRegisterToMemoryPass
-LLVMCreateReassociatePass
-LLVMCreateJumpThreadingPass
-LLVMCreateCFGSimplificationPass
-LLVMCreateBreakCriticalEdgesPass
-LLVMCreateLoopSimplifyPass
-LLVMCreateTailCallEliminationPass
-LLVMCreateLowerSwitchPass
-LLVMCreateLowerInvokePass
-LLVMCreateBlockPlacementPass
-LLVMCreateLCSSAPass
-LLVMCreateEarlyCSEPass
-LLVMCreateGVNPass
-LLVMCreateMemCpyOptPass
-LLVMCreateLoopDeletionPass
-LLVMCreateSimplifyLibCallsPass
-LLVMCreateCodeGenPreparePass
-LLVMCreateInstructionNamerPass
-LLVMCreateSinkingPass
-LLVMCreateLowerAtomicPass
-LLVMCreateCorrelatedValuePropagationPass
-LLVMCreateInstructionSimplifierPass
-LLVMCreateLowerExpectIntrinsicPass
-LLVMCreateBBVectorizePass
-LLVMCreateLoopVectorizePass
-LLVMCreateGlobalsModRefPass
-LLVMCreateAliasAnalysisCounterPass
-LLVMCreateAAEvalPass
-LLVMCreateNoAAPass
-LLVMCreateBasicAliasAnalysisPass
-LLVMCreateScalarEvolutionAliasAnalysisPass
-LLVMCreateTypeBasedAliasAnalysisPass
-LLVMCreateProfileLoaderPass
-LLVMCreateProfileMetadataLoaderPass
-LLVMCreateNoProfileInfoPass
-LLVMCreateProfileEstimatorPass
-LLVMCreateProfileVerifierPass
-LLVMCreatePathProfileLoaderPass
-LLVMCreateNoPathProfileInfoPass
-LLVMCreatePathProfileVerifierPass
-LLVMCreateLazyValueInfoPass
-LLVMCreateDependenceAnalysisPass
-LLVMCreateCostModelAnalysisPass
-LLVMCreateInstCountPass
-LLVMCreateRegionInfoPass
-LLVMCreateModuleDebugInfoPrinterPass
-LLVMCreateLintPass
-LLVMCreateVerifierPass
+LLVMCreatePass