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.
This commit is contained in:
bors 2013-05-29 16:58:44 -07:00
commit b5da389d36
8 changed files with 320 additions and 495 deletions

View File

@ -202,6 +202,8 @@ pub mod write {
output_type: output_type, output_type: output_type,
output: &Path) { output: &Path) {
unsafe { unsafe {
llvm::LLVMInitializePasses();
let opts = sess.opts; let opts = sess.opts;
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); } if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); 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); let mut mpm = passes::PassManager::new(td.lltd);
if !sess.no_verify() { if !sess.no_verify() {
mpm.addPass(llvm::LLVMCreateVerifierPass()); mpm.add_pass_from_name("verify");
} }
if sess.lint_llvm() { let passes = if sess.opts.custom_passes.len() > 0 {
mpm.addPass(llvm::LLVMCreateLintPass()); 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"); debug!("Running Module Optimization Pass");
mpm.run(llmod); mpm.run(llmod);

View File

@ -10,7 +10,8 @@
use core::prelude::*; 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::{PassRef, ModuleRef,PassManagerRef,TargetDataRef};
use lib::llvm::llvm; use lib::llvm::llvm;
use lib; use lib;
@ -39,12 +40,17 @@ impl PassManager {
} }
} }
pub fn addPass(&mut self, pass:PassRef) { pub fn add_pass(&mut self, pass:PassRef) {
unsafe { unsafe {
llvm::LLVMAddPass(self.llpm, pass); 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 { pub fn run(&self, md:ModuleRef) -> bool {
unsafe { unsafe {
llvm::LLVMRunPassManager(self.llpm, md) == lib::llvm::True 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) { if level == No {
unsafe { passes.push(~"always-inline");
// We add a lot of normally-unused prototypes, so always strip them return passes;
// 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());
return; passes.push(~"targetlibinfo");
}
//NOTE: Add library info passes.push(~"tbaa");
passes.push(~"basicaa");
pm.addPass(llvm::LLVMCreateTypeBasedAliasAnalysisPass()); passes.push(~"early-cse");
pm.addPass(llvm::LLVMCreateBasicAliasAnalysisPass());
pm.addPass(llvm::LLVMCreateSROAPass()); passes.push(~"globalopt");
pm.addPass(llvm::LLVMCreateEarlyCSEPass()); passes.push(~"ipsccp");
pm.addPass(llvm::LLVMCreateLowerExpectIntrinsicPass()); passes.push(~"deadargelim");
passes.push(~"instcombine");
passes.push(~"simplifycfg");
pm.addPass(llvm::LLVMCreateGlobalOptimizerPass()); passes.push(~"prune-eh");
pm.addPass(llvm::LLVMCreateIPSCCPPass());
pm.addPass(llvm::LLVMCreateDeadArgEliminationPass());
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
pm.addPass(llvm::LLVMCreatePruneEHPass()); if level == Aggressive {
passes.push(~"mergefunc");
}
if level == session::Aggressive { passes.push(~"inline");
// 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());
}
match level { passes.push(~"functionattrs");
session::Less => pm.addPass(llvm::LLVMCreateFunctionInliningPass(200)),
session::Default => pm.addPass(llvm::LLVMCreateFunctionInliningPass(225)),
session::Aggressive => pm.addPass(llvm::LLVMCreateFunctionInliningPass(275)),
session::No => ()
}
pm.addPass(llvm::LLVMCreateFunctionAttrsPass()); if level == Aggressive {
passes.push(~"argpromotion");
}
if level == session::Aggressive { passes.push(~"early-cse");
pm.addPass(llvm::LLVMCreateArgumentPromotionPass()); passes.push(~"simplify-libcalls");
} passes.push(~"jump-threading");
passes.push(~"correlated-propagation");
passes.push(~"simplifycfg");
passes.push(~"instcombine");
pm.addPass(llvm::LLVMCreateEarlyCSEPass()); passes.push(~"tailcallelim");
pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass()); passes.push(~"simplifycfg");
pm.addPass(llvm::LLVMCreateJumpThreadingPass()); passes.push(~"reassociate");
pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass()); passes.push(~"loop-rotate");
pm.addPass(llvm::LLVMCreateCFGSimplificationPass()); passes.push(~"licm");
pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
pm.addPass(llvm::LLVMCreateTailCallEliminationPass()); passes.push(~"lcssa");
pm.addPass(llvm::LLVMCreateCFGSimplificationPass()); passes.push(~"loop-unswitch");
pm.addPass(llvm::LLVMCreateReassociatePass());
pm.addPass(llvm::LLVMCreateLoopRotatePass());
pm.addPass(llvm::LLVMCreateLICMPass());
pm.addPass(llvm::LLVMCreateInstructionCombiningPass()); passes.push(~"instcombine");
pm.addPass(llvm::LLVMCreateIndVarSimplifyPass()); passes.push(~"indvars");
pm.addPass(llvm::LLVMCreateLoopIdiomPass()); passes.push(~"loop-idiom");
pm.addPass(llvm::LLVMCreateLoopDeletionPass()); passes.push(~"loop-deletion");
if level == session::Aggressive { if level == Aggressive {
pm.addPass(llvm::LLVMCreateLoopVectorizePass()); passes.push(~"loop-vectorize");
} }
pm.addPass(llvm::LLVMCreateLoopUnrollPass());
if level != session::Less { passes.push(~"loop-unroll");
pm.addPass(llvm::LLVMCreateGVNPass());
}
pm.addPass(llvm::LLVMCreateMemCpyOptPass());
pm.addPass(llvm::LLVMCreateSCCPPass());
pm.addPass(llvm::LLVMCreateInstructionCombiningPass()); if level != Less {
pm.addPass(llvm::LLVMCreateJumpThreadingPass()); passes.push(~"gvn");
pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass()); }
pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());
pm.addPass(llvm::LLVMCreateBBVectorizePass()); passes.push(~"memcpyopt");
pm.addPass(llvm::LLVMCreateInstructionCombiningPass()); passes.push(~"sccp");
pm.addPass(llvm::LLVMCreateEarlyCSEPass());
pm.addPass(llvm::LLVMCreateLoopUnrollPass()); passes.push(~"instcombine");
passes.push(~"jump-threading");
passes.push(~"correlated-propagation");
passes.push(~"dse");
pm.addPass(llvm::LLVMCreateAggressiveDCEPass()); passes.push(~"bb-vectorize");
pm.addPass(llvm::LLVMCreateCFGSimplificationPass()); passes.push(~"instcombine");
pm.addPass(llvm::LLVMCreateInstructionSimplifierPass()); passes.push(~"early-cse");
if level != session::Less { passes.push(~"loop-unroll");
pm.addPass(llvm::LLVMCreateGlobalDCEPass());
pm.addPass(llvm::LLVMCreateConstantMergePass()); 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

@ -679,11 +679,24 @@ pub fn build_session_options(binary: @~str,
let android_cross_path = getopts::opt_maybe_str( let android_cross_path = getopts::opt_maybe_str(
matches, "android-cross-path"); 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 { let sopts = @session::options {
crate_type: crate_type, crate_type: crate_type,
is_static: statik, is_static: statik,
gc: gc, gc: gc,
optimize: opt_level, optimize: opt_level,
custom_passes: custom_passes,
debuginfo: debuginfo, debuginfo: debuginfo,
extra_debuginfo: extra_debuginfo, extra_debuginfo: extra_debuginfo,
lint_opts: lint_opts, lint_opts: lint_opts,
@ -785,6 +798,9 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
optopt("o", "", "Write output to <filename>", "FILENAME"), optopt("o", "", "Write output to <filename>", "FILENAME"),
optopt("", "opt-level", optopt("", "opt-level",
"Optimize with possible levels 0-3", "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", optopt( "", "out-dir",
"Write output to compiler-chosen filename "Write output to compiler-chosen filename
in <dir>", "DIR"), in <dir>", "DIR"),

View File

@ -129,6 +129,7 @@ pub struct options {
is_static: bool, is_static: bool,
gc: bool, gc: bool,
optimize: OptLevel, optimize: OptLevel,
custom_passes: ~[~str],
debuginfo: bool, debuginfo: bool,
extra_debuginfo: bool, extra_debuginfo: bool,
lint_opts: ~[(lint::lint, lint::level)], lint_opts: ~[(lint::lint, lint::level)],
@ -304,6 +305,7 @@ pub fn basic_options() -> @options {
is_static: false, is_static: false,
gc: false, gc: false,
optimize: No, optimize: No,
custom_passes: ~[],
debuginfo: false, debuginfo: false,
extra_debuginfo: false, extra_debuginfo: false,
lint_opts: ~[], lint_opts: ~[],

View File

@ -1681,9 +1681,15 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMFinalizeFunctionPassManager(FPM:PassManagerRef) -> Bool; pub unsafe fn LLVMFinalizeFunctionPassManager(FPM:PassManagerRef) -> Bool;
#[fast_ffi]
pub unsafe fn LLVMInitializePasses();
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMAddPass(PM:PassManagerRef,P:PassRef); pub unsafe fn LLVMAddPass(PM:PassManagerRef,P:PassRef);
#[fast_ffi]
pub unsafe fn LLVMCreatePass(PassName:*c_char) -> PassRef;
/** Adds a verification pass. */ /** Adds a verification pass. */
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMAddVerifierPass(PM: PassManagerRef); pub unsafe fn LLVMAddVerifierPass(PM: PassManagerRef);
@ -1926,202 +1932,6 @@ pub mod llvm {
AlignStack: Bool, Dialect: c_uint) AlignStack: Bool, Dialect: c_uint)
-> ValueRef; -> 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; return;
} }
if getopts::opt_maybe_str(matches, "passes") == Some(~"list") {
back::passes::list_passes();
return;
}
if opt_present(matches, "v") || opt_present(matches, "version") { if opt_present(matches, "v") || opt_present(matches, "version") {
version(*binary); version(*binary);
return; return;

View File

@ -30,10 +30,20 @@ inline T *unwrap(LLVMPassRef P) {
return Q; return Q;
} }
#define WRAP_PASS(name) \ extern "C" void LLVMInitializePasses() {
extern "C" LLVMPassRef LLVMCreate##name##Pass() { \ PassRegistry &Registry = *PassRegistry::getPassRegistry();
return wrap(llvm::create##name##Pass()); \ 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) { extern "C" void LLVMAddPass(LLVMPassManagerRef PM, LLVMPassRef P) {
PassManagerBase * pm = unwrap(PM); PassManagerBase * pm = unwrap(PM);
@ -42,119 +52,14 @@ extern "C" void LLVMAddPass(LLVMPassManagerRef PM, LLVMPassRef P) {
pm->add(p); pm->add(p);
} }
//////////////// extern "C" LLVMPassRef LLVMCreatePass(const char * PassName) {
// Transforms // StringRef SR(PassName);
// ///////////// PassRegistry * PR = PassRegistry::getPassRegistry();
// IPO Passes const PassInfo * PI = PR->getPassInfo(SR);
WRAP_PASS(StripSymbols) if (PI) {
WRAP_PASS(StripNonDebugSymbols) return wrap(PI->createPass());
WRAP_PASS(StripDebugDeclare) } else {
WRAP_PASS(StripDeadDebugInfo) return (LLVMPassRef)0;
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 LLVMCreateFunctionInliningPass(int Threshold) {
return wrap(llvm::createFunctionInliningPass(Threshold));
} }
// 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)

View File

@ -584,102 +584,6 @@ LLVMConstNamedStruct
LLVMStructCreateNamed LLVMStructCreateNamed
LLVMStructSetBody LLVMStructSetBody
LLVMInlineAsm LLVMInlineAsm
LLVMInitializePasses
LLVMAddPass LLVMAddPass
LLVMCreatePass
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