From faf1afee16cfacf0318ca2b88bc4fa5e507418dd Mon Sep 17 00:00:00 2001 From: James Miller Date: Wed, 29 May 2013 20:08:20 +1200 Subject: [PATCH] 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. --- src/librustc/back/link.rs | 19 +- src/librustc/back/passes.rs | 332 +++++++++++++++++++++++++-------- src/librustc/driver/driver.rs | 16 ++ src/librustc/driver/session.rs | 2 + src/librustc/lib/llvm.rs | 202 +------------------- src/librustc/rustc.rc | 5 + src/rustllvm/PassWrapper.cpp | 141 +++----------- src/rustllvm/rustllvm.def.in | 100 +--------- 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 fn run_passes(sess: Session, 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 fn run_passes(sess: Session, 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 @@ pub fn new(td: TargetDataRef) -> 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 @@ pub fn run(&self, md:ModuleRef) -> bool { } } +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 { + 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 64d3b0e373c..b256caa9b74 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -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"), 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"), 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 @@ -1681,9 +1681,15 @@ pub unsafe fn LLVMRunPassManager(PM: PassManagerRef, #[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 unsafe fn LLVMInlineAsm(Ty: TypeRef, AsmString: *c_char, 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 -- GitLab