Further refactor optimization pass handling

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.
This commit is contained in:
James Miller 2013-05-29 20:08:20 +12:00
parent 4ad0b8ac58
commit faf1afee16
8 changed files with 320 additions and 495 deletions

View file

@ -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);

View file

@ -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");
pm.addPass(llvm::LLVMCreateEarlyCSEPass());
pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass());
pm.addPass(llvm::LLVMCreateJumpThreadingPass());
pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
passes.push(~"tailcallelim");
passes.push(~"simplifycfg");
passes.push(~"reassociate");
passes.push(~"loop-rotate");
passes.push(~"licm");
pm.addPass(llvm::LLVMCreateTailCallEliminationPass());
pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
pm.addPass(llvm::LLVMCreateReassociatePass());
pm.addPass(llvm::LLVMCreateLoopRotatePass());
pm.addPass(llvm::LLVMCreateLICMPass());
passes.push(~"lcssa");
passes.push(~"loop-unswitch");
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
pm.addPass(llvm::LLVMCreateIndVarSimplifyPass());
pm.addPass(llvm::LLVMCreateLoopIdiomPass());
pm.addPass(llvm::LLVMCreateLoopDeletionPass());
passes.push(~"instcombine");
passes.push(~"indvars");
passes.push(~"loop-idiom");
passes.push(~"loop-deletion");
if level == session::Aggressive {
pm.addPass(llvm::LLVMCreateLoopVectorizePass());
}
pm.addPass(llvm::LLVMCreateLoopUnrollPass());
if level == Aggressive {
passes.push(~"loop-vectorize");
}
if level != session::Less {
pm.addPass(llvm::LLVMCreateGVNPass());
}
pm.addPass(llvm::LLVMCreateMemCpyOptPass());
pm.addPass(llvm::LLVMCreateSCCPPass());
passes.push(~"loop-unroll");
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
pm.addPass(llvm::LLVMCreateJumpThreadingPass());
pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());
if level != Less {
passes.push(~"gvn");
}
pm.addPass(llvm::LLVMCreateBBVectorizePass());
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
pm.addPass(llvm::LLVMCreateEarlyCSEPass());
passes.push(~"memcpyopt");
passes.push(~"sccp");
pm.addPass(llvm::LLVMCreateLoopUnrollPass());
passes.push(~"instcombine");
passes.push(~"jump-threading");
passes.push(~"correlated-propagation");
passes.push(~"dse");
pm.addPass(llvm::LLVMCreateAggressiveDCEPass());
pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
pm.addPass(llvm::LLVMCreateInstructionSimplifierPass());
passes.push(~"bb-vectorize");
passes.push(~"instcombine");
passes.push(~"early-cse");
if level != session::Less {
pm.addPass(llvm::LLVMCreateGlobalDCEPass());
pm.addPass(llvm::LLVMCreateConstantMergePass());
passes.push(~"loop-unroll");
passes.push(~"adce");
passes.push(~"simplifycfg");
passes.push(~"instsimplify");
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))
}
}
}
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)
}
}
}
}
pub fn list_passes() {
io::println("\nAvailable Passes:");
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"),
];
/** 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"),
];
/** 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 failed.len() > 0 {
io::println("Some passes don't exist:");
for failed.each |&n| {
io::println(fmt!(" %s", n));
}
fail!();
}
}

View file

@ -677,11 +677,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,
@ -783,6 +796,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"),

View file

@ -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: ~[],

View file

@ -1681,9 +1681,15 @@ pub mod llvm {
#[fast_ffi]
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;
}
}

View file

@ -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;