diff options
| -rw-r--r-- | src/comp/back/Link.rs | 176 | ||||
| -rw-r--r-- | src/comp/driver/rustc.rs | 29 | ||||
| -rw-r--r-- | src/comp/driver/session.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 162 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 1 |
5 files changed, 197 insertions, 173 deletions
diff --git a/src/comp/back/Link.rs b/src/comp/back/Link.rs new file mode 100644 index 00000000..5d9eb9d6 --- /dev/null +++ b/src/comp/back/Link.rs @@ -0,0 +1,176 @@ +import driver.session; +import lib.llvm.llvm; +import middle.trans; +import std._str; + +import lib.llvm.llvm.ModuleRef; +import lib.llvm.llvm.ValueRef; +import lib.llvm.mk_pass_manager; +import lib.llvm.mk_target_data; +import lib.llvm.mk_type_names; + +tag output_type { + output_type_none; + output_type_bitcode; + output_type_assembly; + output_type_object; +} + +mod Write { + fn is_object_or_assembly(output_type ot) -> bool { + if (ot == output_type_assembly) { + ret true; + } + if (ot == output_type_object) { + ret true; + } + ret false; + } + + // Decides what to call an intermediate file, given the name of the output + // and the extension to use. + fn mk_intermediate_name(str output_path, str extension) -> str { + auto dot_pos = _str.index(output_path, '.' as u8); + auto stem; + if (dot_pos < 0) { + stem = output_path; + } else { + stem = _str.substr(output_path, 0u, dot_pos as uint); + } + ret stem + "." + extension; + } + + fn run_passes(session.session sess, ModuleRef llmod, str output) { + auto pm = mk_pass_manager(); + auto opts = sess.get_opts(); + + // TODO: run the linter here also, once there are llvm-c bindings for + // it. + + // Generate a pre-optimization intermediate file if -save-temps was + // specified. + if (opts.save_temps) { + alt (opts.output_type) { + case (output_type_bitcode) { + if (opts.optimize) { + auto filename = mk_intermediate_name(output, + "no-opt.bc"); + llvm.LLVMWriteBitcodeToFile(llmod, + _str.buf(filename)); + } + } + case (_) { + auto filename = mk_intermediate_name(output, "bc"); + llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename)); + } + } + } + + // FIXME: This is mostly a copy of the bits of opt's -O2 that are + // available in the C api. + // FIXME2: We might want to add optimization levels like -O1, -O2, + // -Os, etc + // FIXME3: Should we expose and use the pass lists used by the opt + // tool? + if (opts.optimize) { + auto fpm = mk_pass_manager(); + + // createStandardFunctionPasses + llvm.LLVMAddTypeBasedAliasAnalysisPass(fpm.llpm); + llvm.LLVMAddBasicAliasAnalysisPass(fpm.llpm); + llvm.LLVMAddCFGSimplificationPass(fpm.llpm); + llvm.LLVMAddScalarReplAggregatesPass(fpm.llpm); + llvm.LLVMAddEarlyCSEPass(fpm.llpm); + + llvm.LLVMRunPassManager(fpm.llpm, llmod); + + // createStandardModulePasses + llvm.LLVMAddTypeBasedAliasAnalysisPass(pm.llpm); + llvm.LLVMAddBasicAliasAnalysisPass(pm.llpm); + llvm.LLVMAddGlobalOptimizerPass(pm.llpm); + llvm.LLVMAddIPSCCPPass(pm.llpm); + llvm.LLVMAddDeadArgEliminationPass(pm.llpm); + llvm.LLVMAddInstructionCombiningPass(pm.llpm); + llvm.LLVMAddCFGSimplificationPass(pm.llpm); + llvm.LLVMAddPruneEHPass(pm.llpm); + llvm.LLVMAddFunctionInliningPass(pm.llpm); + llvm.LLVMAddFunctionAttrsPass(pm.llpm); + llvm.LLVMAddScalarReplAggregatesPassSSA(pm.llpm); + llvm.LLVMAddEarlyCSEPass(pm.llpm); + llvm.LLVMAddSimplifyLibCallsPass(pm.llpm); + llvm.LLVMAddJumpThreadingPass(pm.llpm); + llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm); + llvm.LLVMAddCFGSimplificationPass(pm.llpm); + llvm.LLVMAddInstructionCombiningPass(pm.llpm); + llvm.LLVMAddTailCallEliminationPass(pm.llpm); + llvm.LLVMAddCFGSimplificationPass(pm.llpm); + llvm.LLVMAddReassociatePass(pm.llpm); + llvm.LLVMAddLoopRotatePass(pm.llpm); + llvm.LLVMAddLICMPass(pm.llpm); + llvm.LLVMAddLoopUnswitchPass(pm.llpm); + llvm.LLVMAddInstructionCombiningPass(pm.llpm); + llvm.LLVMAddIndVarSimplifyPass(pm.llpm); + llvm.LLVMAddLoopIdiomPass(pm.llpm); + llvm.LLVMAddLoopDeletionPass(pm.llpm); + llvm.LLVMAddLoopUnrollPass(pm.llpm); + llvm.LLVMAddInstructionCombiningPass(pm.llpm); + llvm.LLVMAddGVNPass(pm.llpm); + llvm.LLVMAddMemCpyOptPass(pm.llpm); + llvm.LLVMAddSCCPPass(pm.llpm); + llvm.LLVMAddInstructionCombiningPass(pm.llpm); + llvm.LLVMAddJumpThreadingPass(pm.llpm); + llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm); + llvm.LLVMAddDeadStoreEliminationPass(pm.llpm); + llvm.LLVMAddAggressiveDCEPass(pm.llpm); + llvm.LLVMAddCFGSimplificationPass(pm.llpm); + llvm.LLVMAddStripDeadPrototypesPass(pm.llpm); + llvm.LLVMAddDeadTypeEliminationPass(pm.llpm); + llvm.LLVMAddConstantMergePass(pm.llpm); + } + + if (opts.verify) { + llvm.LLVMAddVerifierPass(pm.llpm); + } + + // TODO: Write .s if -c was specified and -save-temps was on. + if (is_object_or_assembly(opts.output_type)) { + let int LLVMAssemblyFile = 0; + let int LLVMObjectFile = 1; + let int LLVMNullFile = 2; + auto FileType; + if (opts.output_type == output_type_object) { + FileType = LLVMObjectFile; + } else { + FileType = LLVMAssemblyFile; + } + + // Write optimized bitcode if --save-temps was on. + if (opts.save_temps) { + alt (opts.output_type) { + case (output_type_bitcode) { /* nothing to do */ } + case (_) { + auto filename = mk_intermediate_name(output, + "opt.bc"); + llvm.LLVMRunPassManager(pm.llpm, llmod); + llvm.LLVMWriteBitcodeToFile(llmod, + _str.buf(filename)); + pm = mk_pass_manager(); + } + } + } + + llvm.LLVMRustWriteOutputFile(pm.llpm, llmod, + _str.buf(x86.get_target_triple()), + _str.buf(output), + FileType); + llvm.LLVMDisposeModule(llmod); + ret; + } + + llvm.LLVMRunPassManager(pm.llpm, llmod); + + llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output)); + llvm.LLVMDisposeModule(llmod); + } +} + diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 4276b558..dd10eee5 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -11,6 +11,7 @@ import middle.capture; import middle.ty; import middle.typeck; import middle.typestate_check; +import back.Link; import lib.llvm; import util.common; @@ -30,6 +31,8 @@ import std.GetOpts.optmulti; import std.GetOpts.optflag; import std.GetOpts.opt_present; +import back.Link.output_type; + fn default_environment(session.session sess, str argv0, str input) -> eval.env { @@ -86,7 +89,7 @@ fn compile_input(session.session sess, auto p = parser.new_parser(sess, env, def, input, 0u); auto crate = time[@ast.crate](time_passes, "parsing", bind parse_input(sess, p, input)); - if (sess.get_opts().output_type == trans.output_type_none) {ret;} + if (sess.get_opts().output_type == Link.output_type_none) {ret;} crate = time[@ast.crate](time_passes, "external crate reading", bind creader.read_crates(sess, crate)); @@ -111,7 +114,7 @@ fn compile_input(session.session sess, bind trans.trans_crate(sess, crate, ty_cx, type_cache, output)); time[()](time_passes, "LLVM passes", - bind trans.run_passes(sess, llmod, output)); + bind Link.Write.run_passes(sess, llmod, output)); } fn pretty_print_input(session.session sess, @@ -197,14 +200,16 @@ fn main(vec[str] args) { auto shared = opt_present(match, "shared"); auto output_file = GetOpts.opt_maybe_str(match, "o"); auto library_search_paths = GetOpts.opt_strs(match, "L"); - auto output_type = trans.output_type_bitcode; + + auto output_type = Link.output_type_bitcode; if (opt_present(match, "parse-only")) { - output_type = trans.output_type_none; + output_type = Link.output_type_none; } else if (opt_present(match, "S")) { - output_type = trans.output_type_assembly; + output_type = Link.output_type_assembly; } else if (opt_present(match, "c")) { - output_type = trans.output_type_object; + output_type = Link.output_type_object; } + auto verify = !opt_present(match, "noverify"); auto save_temps = opt_present(match, "save-temps"); // FIXME: Maybe we should support -O0, -O1, -Os, etc @@ -268,14 +273,10 @@ fn main(vec[str] args) { let vec[str] parts = _str.split(ifile, '.' as u8); _vec.pop[str](parts); alt (output_type) { - case (trans.output_type_none) - { parts += vec("pp"); } - case (trans.output_type_bitcode) - { parts += vec("bc"); } - case (trans.output_type_assembly) - { parts += vec("s"); } - case (trans.output_type_object) - { parts += vec("o"); } + case (Link.output_type_none) { parts += vec("pp"); } + case (Link.output_type_bitcode) { parts += vec("bc"); } + case (Link.output_type_assembly) { parts += vec("s"); } + case (Link.output_type_object) { parts += vec("o"); } } auto ofile = _str.connect(parts, "."); compile_input(sess, env, ifile, ofile); diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 6b3b55f4..cf34bb7c 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -32,7 +32,7 @@ type options = rec(bool shared, bool run_typestate, bool save_temps, bool time_passes, - middle.trans.output_type output_type, + back.Link.output_type output_type, vec[str] library_search_paths, str sysroot); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 3a654da8..b479efef 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -15,6 +15,7 @@ import front.creader; import pretty.pprust; import driver.session; import middle.ty; +import back.Link; import back.x86; import back.abi; @@ -32,7 +33,6 @@ import lib.llvm.builder; import lib.llvm.target_data; import lib.llvm.type_handle; import lib.llvm.type_names; -import lib.llvm.mk_pass_manager; import lib.llvm.mk_target_data; import lib.llvm.mk_type_handle; import lib.llvm.mk_type_names; @@ -7217,161 +7217,6 @@ fn trap(@block_ctxt bcx) { let vec[ValueRef] v = vec(); bcx.build.Call(bcx.fcx.lcx.ccx.intrinsics.get("llvm.trap"), v); } -tag output_type { - output_type_none; - output_type_bitcode; - output_type_assembly; - output_type_object; -} - -// Decides what to call an intermediate file, given the name of the output and -// the extension to use. -fn mk_intermediate_name(str output_path, str extension) -> str { - auto dot_pos = _str.index(output_path, '.' as u8); - auto stem; - if (dot_pos < 0) { - stem = output_path; - } else { - stem = _str.substr(output_path, 0u, dot_pos as uint); - } - ret stem + "." + extension; -} - -fn is_object_or_assembly(output_type ot) -> bool { - if (ot == output_type_assembly) { - ret true; - } - if (ot == output_type_object) { - ret true; - } - ret false; -} - -fn run_passes(session.session sess, ModuleRef llmod, str output) { - auto pm = mk_pass_manager(); - auto opts = sess.get_opts(); - - // TODO: run the linter here also, once there are llvm-c bindings for it. - - // Generate a pre-optimization intermediate file if -save-temps was - // specified. - if (opts.save_temps) { - alt (opts.output_type) { - case (output_type_bitcode) { - if (opts.optimize) { - auto filename = mk_intermediate_name(output, "no-opt.bc"); - llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename)); - } - } - case (_) { - auto filename = mk_intermediate_name(output, "bc"); - llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename)); - } - } - } - - // FIXME: This is mostly a copy of the bits of opt's -O2 that are - // available in the C api. - // FIXME2: We might want to add optmization levels like -O1, -O2, -Os, etc - // FIXME3: Should we expose and use the pass lists used by the opt tool? - if (opts.optimize) { - auto fpm = mk_pass_manager(); - - // createStandardFunctionPasses - llvm.LLVMAddTypeBasedAliasAnalysisPass(fpm.llpm); - llvm.LLVMAddBasicAliasAnalysisPass(fpm.llpm); - llvm.LLVMAddCFGSimplificationPass(fpm.llpm); - llvm.LLVMAddScalarReplAggregatesPass(fpm.llpm); - llvm.LLVMAddEarlyCSEPass(fpm.llpm); - - llvm.LLVMRunPassManager(fpm.llpm, llmod); - - // createStandardModulePasses - llvm.LLVMAddTypeBasedAliasAnalysisPass(pm.llpm); - llvm.LLVMAddBasicAliasAnalysisPass(pm.llpm); - llvm.LLVMAddGlobalOptimizerPass(pm.llpm); - llvm.LLVMAddIPSCCPPass(pm.llpm); - llvm.LLVMAddDeadArgEliminationPass(pm.llpm); - llvm.LLVMAddInstructionCombiningPass(pm.llpm); - llvm.LLVMAddCFGSimplificationPass(pm.llpm); - llvm.LLVMAddPruneEHPass(pm.llpm); - llvm.LLVMAddFunctionInliningPass(pm.llpm); - llvm.LLVMAddFunctionAttrsPass(pm.llpm); - llvm.LLVMAddScalarReplAggregatesPassSSA(pm.llpm); - llvm.LLVMAddEarlyCSEPass(pm.llpm); - llvm.LLVMAddSimplifyLibCallsPass(pm.llpm); - llvm.LLVMAddJumpThreadingPass(pm.llpm); - llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm); - llvm.LLVMAddCFGSimplificationPass(pm.llpm); - llvm.LLVMAddInstructionCombiningPass(pm.llpm); - llvm.LLVMAddTailCallEliminationPass(pm.llpm); - llvm.LLVMAddCFGSimplificationPass(pm.llpm); - llvm.LLVMAddReassociatePass(pm.llpm); - llvm.LLVMAddLoopRotatePass(pm.llpm); - llvm.LLVMAddLICMPass(pm.llpm); - llvm.LLVMAddLoopUnswitchPass(pm.llpm); - llvm.LLVMAddInstructionCombiningPass(pm.llpm); - llvm.LLVMAddIndVarSimplifyPass(pm.llpm); - llvm.LLVMAddLoopIdiomPass(pm.llpm); - llvm.LLVMAddLoopDeletionPass(pm.llpm); - llvm.LLVMAddLoopUnrollPass(pm.llpm); - llvm.LLVMAddInstructionCombiningPass(pm.llpm); - llvm.LLVMAddGVNPass(pm.llpm); - llvm.LLVMAddMemCpyOptPass(pm.llpm); - llvm.LLVMAddSCCPPass(pm.llpm); - llvm.LLVMAddInstructionCombiningPass(pm.llpm); - llvm.LLVMAddJumpThreadingPass(pm.llpm); - llvm.LLVMAddCorrelatedValuePropagationPass(pm.llpm); - llvm.LLVMAddDeadStoreEliminationPass(pm.llpm); - llvm.LLVMAddAggressiveDCEPass(pm.llpm); - llvm.LLVMAddCFGSimplificationPass(pm.llpm); - llvm.LLVMAddStripDeadPrototypesPass(pm.llpm); - llvm.LLVMAddDeadTypeEliminationPass(pm.llpm); - llvm.LLVMAddConstantMergePass(pm.llpm); - } - - if (opts.verify) { - llvm.LLVMAddVerifierPass(pm.llpm); - } - - // TODO: Write .s if -c was specified and -save-temps was on. - if (is_object_or_assembly(opts.output_type)) { - let int LLVMAssemblyFile = 0; - let int LLVMObjectFile = 1; - let int LLVMNullFile = 2; - auto FileType; - if (opts.output_type == output_type_object) { - FileType = LLVMObjectFile; - } else { - FileType = LLVMAssemblyFile; - } - - // Write optimized bitcode if --save-temps was on. - if (opts.save_temps) { - alt (opts.output_type) { - case (output_type_bitcode) { /* nothing to do */ } - case (_) { - auto filename = mk_intermediate_name(output, "opt.bc"); - llvm.LLVMRunPassManager(pm.llpm, llmod); - llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(filename)); - pm = mk_pass_manager(); - } - } - } - - llvm.LLVMRustWriteOutputFile(pm.llpm, llmod, - _str.buf(x86.get_target_triple()), - _str.buf(output), - FileType); - llvm.LLVMDisposeModule(llmod); - ret; - } - - llvm.LLVMRunPassManager(pm.llpm, llmod); - - llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output)); - llvm.LLVMDisposeModule(llmod); -} fn decl_no_op_type_glue(ModuleRef llmod, type_names tn) -> ValueRef { auto ty = T_fn(vec(T_taskptr(tn), T_ptr(T_i8())), T_void()); @@ -7736,9 +7581,10 @@ fn make_common_glue(session.session sess, str output) { make_memcpy_glue(glues.memcpy_glue); make_bzero_glue(glues.bzero_glue); - trans_exit_task_glue(glues, new_str_hash[ValueRef](), tn, llmod); + trans.trans_exit_task_glue(glues, new_str_hash[ValueRef](), tn, + llmod); - run_passes(sess, llmod, output); + Link.Write.run_passes(sess, llmod, output); } fn create_module_map(@crate_ctxt ccx) -> ValueRef { diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 3074a84d..4f4b0849 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -33,6 +33,7 @@ mod front { } mod back { + mod Link; mod abi; mod x86; } |