use -Z to distinguish internal debugging options

This commit is contained in:
Niko Matsakis 2012-05-17 21:53:49 -07:00
parent 0eef34bacb
commit 5be8bf1de7
9 changed files with 98 additions and 77 deletions

View File

@ -91,14 +91,11 @@ endif
ifdef SAVE_TEMPS
CFG_RUSTC_FLAGS += --save-temps
endif
ifdef ENFORCE_MUT_VARS
CFG_RUSTC_FLAGS += --enforce-mut-vars
endif
ifdef TIME_PASSES
CFG_RUSTC_FLAGS += --time-passes
CFG_RUSTC_FLAGS += -Z time-passes
endif
ifdef TIME_LLVM_PASSES
CFG_RUSTC_FLAGS += --time-llvm-passes
CFG_RUSTC_FLAGS += -Z time-llvm-passes
endif
# platform-specific auto-configuration

View File

@ -53,7 +53,7 @@ mod write {
fn run_passes(sess: session, llmod: ModuleRef, output: str) {
let opts = sess.opts;
if opts.time_llvm_passes { llvm::LLVMRustEnableTimePasses(); }
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let mut pm = mk_pass_manager();
let td = mk_target_data(
sess.targ_cfg.target_strs.data_layout);
@ -84,7 +84,7 @@ mod write {
}
}
}
if opts.verify { llvm::LLVMAddVerifierPass(pm.llpm); }
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
// 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,
@ -125,7 +125,7 @@ mod write {
llvm::LLVMPassManagerBuilderDispose(MPMB);
}
if opts.verify { llvm::LLVMAddVerifierPass(pm.llpm); }
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
if is_object_or_assembly_or_exe(opts.output_type) {
let LLVMOptNone = 0 as c_int; // -O0
let LLVMOptLess = 1 as c_int; // -O1
@ -214,7 +214,7 @@ mod write {
// Clean up and return
llvm::LLVMDisposeModule(llmod);
if opts.time_llvm_passes { llvm::LLVMRustPrintPassTimings(); }
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
ret;
}
@ -231,7 +231,7 @@ mod write {
}
llvm::LLVMDisposeModule(llmod);
if opts.time_llvm_passes { llvm::LLVMRustPrintPassTimings(); }
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
}
}

View File

@ -129,7 +129,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
input: input, upto: compile_upto,
outputs: option<output_filenames>)
-> {crate: @ast::crate, tcx: option<ty::ctxt>} {
let time_passes = sess.opts.time_passes;
let time_passes = sess.time_passes();
let mut crate = time(time_passes, "parsing",
bind parse_input(sess, cfg, input));
if upto == cu_parse { ret {crate: crate, tcx: none}; }
@ -404,6 +404,21 @@ fn build_session_options(match: getopts::match,
}
};
let mut debugging_opts = 0u;
let debug_flags = getopts::opt_strs(match, "Z");
let debug_map = session::debugging_opts_map();
for debug_flags.each { |debug_flag|
let mut this_bit = 0u;
for debug_map.each { |pair|
let (name, _, bit) = pair;
if name == debug_flag { this_bit = bit; break; }
}
if this_bit == 0u {
early_error(demitter, #fmt("unknown debug flag: %s", debug_flag))
}
debugging_opts |= this_bit;
}
let output_type =
if parse_only || no_trans {
link::output_type_none
@ -416,18 +431,11 @@ fn build_session_options(match: getopts::match,
} else if opt_present(match, "emit-llvm") {
link::output_type_bitcode
} else { link::output_type_exe };
let verify = !opt_present(match, "no-verify");
let save_temps = opt_present(match, "save-temps");
let extra_debuginfo = opt_present(match, "xg");
let debuginfo = opt_present(match, "g") || extra_debuginfo;
let stats = opt_present(match, "stats");
let time_passes = opt_present(match, "time-passes");
let time_llvm_passes = opt_present(match, "time-llvm-passes");
let count_llvm_insns = opt_present(match, "count-llvm-insns");
let sysroot_opt = getopts::opt_maybe_str(match, "sysroot");
let target_opt = getopts::opt_maybe_str(match, "target");
let mut no_asm_comments = getopts::opt_present(match, "no-asm-comments");
let debug_rustc = getopts::opt_present(match, "debug-rustc");
let save_temps = getopts::opt_present(match, "save-temps");
let borrowck = alt getopts::opt_maybe_str(match, "borrowck") {
none { 0u }
some("warn") { 1u }
@ -439,7 +447,7 @@ fn build_session_options(match: getopts::match,
alt output_type {
// unless we're emitting huamn-readable assembly, omit comments.
link::output_type_llvm_assembly | link::output_type_assembly {}
_ { no_asm_comments = true; }
_ { debugging_opts |= session::no_asm_comments; }
}
let opt_level: uint =
if opt_present(match, "O") {
@ -474,13 +482,8 @@ fn build_session_options(match: getopts::match,
optimize: opt_level,
debuginfo: debuginfo,
extra_debuginfo: extra_debuginfo,
verify: verify,
lint_opts: lint_opts,
save_temps: save_temps,
stats: stats,
time_passes: time_passes,
count_llvm_insns: count_llvm_insns,
time_llvm_passes: time_llvm_passes,
output_type: output_type,
addl_lib_search_paths: addl_lib_search_paths,
maybe_sysroot: sysroot_opt,
@ -489,8 +492,7 @@ fn build_session_options(match: getopts::match,
test: test,
parse_only: parse_only,
no_trans: no_trans,
no_asm_comments: no_asm_comments,
debug_rustc: debug_rustc,
debugging_opts: debugging_opts,
borrowck: borrowck};
ret sopts;
}
@ -559,17 +561,14 @@ fn opts() -> [getopts::opt] {
optflag("O"), optopt("opt-level"), optmulti("L"), optflag("S"),
optopt("o"), optopt("out-dir"), optflag("xg"),
optflag("c"), optflag("g"), optflag("save-temps"),
optopt("sysroot"), optopt("target"), optflag("stats"),
optflag("time-passes"), optflag("time-llvm-passes"),
optflag("count-llvm-insns"),
optflag("no-verify"),
optopt("sysroot"), optopt("target"),
optmulti("W"), optmulti("warn"),
optmulti("Z"),
optmulti("cfg"), optflag("test"),
optflag("lib"), optflag("bin"), optflag("static"), optflag("gc"),
optflag("no-asm-comments"),
optflag("debug-rustc"),
optopt("borrowck")];
}

View File

@ -14,7 +14,7 @@ import std::map::hashmap;
import getopts::{opt_present};
import rustc::driver::driver::*;
import syntax::codemap;
import rustc::driver::diagnostic;
import rustc::driver::{diagnostic, session};
import rustc::middle::lint;
import io::reader_util;
@ -41,10 +41,7 @@ Options:
-L <path> Add a directory to the library search path
--lib Compile a library crate
--ls List the symbols defined by a compiled library crate
--no-asm-comments Do not add comments into the assembly source
--no-trans Run all passes except translation; no output
--no-verify Suppress LLVM verification step (slight speedup)
(see http://llvm.org/docs/Passes.html for detail)
-O Equivalent to --opt-level=2
-o <filename> Write output to <filename>
--opt-level <lvl> Optimize with possible levels 0-3
@ -66,18 +63,13 @@ Options:
(default: host triple)
(see http://sources.redhat.com/autobook/autobook/
autobook_17.html for detail)
--debug-rustc enables different output that helps in debugging rustc,
but may be less clear for normal use
-W <foo> enable warning <foo>
-W no-<foo> disable warning <foo>
-W err-<foo> enable warning <foo> as an error
-W help Print available warnings and default settings
--time-passes Time the individual phases of the compiler
--time-llvm-passes Time the individual phases of the LLVM backend
--count-llvm-insns Count and categorize generated LLVM instructions
-Z help list internal options for debugging rustc
-v --version Print version info and exit
");
@ -107,6 +99,14 @@ fn describe_warnings() {
io::println("");
}
fn describe_debug_flags() {
io::println(#fmt("\nAvailable debug options:\n"));
for session::debugging_opts_map().each { |pair|
let (name, desc, _) = pair;
io::println(#fmt(" -Z%-20s -- %s", name, desc));
}
}
fn run_compiler(args: [str], demitter: diagnostic::emitter) {
// Don't display log spew by default. Can override with RUST_LOG.
logging::console_off();
@ -136,6 +136,11 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
ret;
}
if getopts::opt_strs(match, "Z").contains("help") {
describe_debug_flags();
ret;
}
if opt_present(match, "v") || opt_present(match, "version") {
version(binary);
ret;

View File

@ -23,6 +23,26 @@ type config =
uint_type: uint_ty,
float_type: float_ty};
const ppregions: uint = 1u;
const time_passes: uint = 2u;
const count_llvm_insns: uint = 4u;
const time_llvm_passes: uint = 8u;
const stats: uint = 16u;
const no_asm_comments: uint = 32u;
const no_verify: uint = 64u;
fn debugging_opts_map() -> [(str, str, uint)] {
[("ppregions", "prettyprint regions with \
internal repr details", ppregions),
("time-passes", "measure time of each rustc pass", time_passes),
("count-llvm-insns", "count where LLVM \
instrs originate", count_llvm_insns),
("time-llvm-passes", "measure time of each LLVM pass", time_llvm_passes),
("stats", "gather trans statistics", stats),
("no-asm-comments", "omit comments when using -S", no_asm_comments),
("no-verify", "skip LLVM verification", no_verify)]
}
type options =
// The crate config requested for the session, which may be combined
// with additional crate configurations during the compile process
@ -31,13 +51,8 @@ type options =
optimize: uint,
debuginfo: bool,
extra_debuginfo: bool,
verify: bool,
lint_opts: [(lint::lint, lint::level)],
save_temps: bool,
stats: bool,
time_passes: bool,
count_llvm_insns: bool,
time_llvm_passes: bool,
output_type: back::link::output_type,
addl_lib_search_paths: [str],
maybe_sysroot: option<str>,
@ -46,8 +61,8 @@ type options =
test: bool,
parse_only: bool,
no_trans: bool,
no_asm_comments: bool,
debug_rustc: bool,
debugging_opts: uint,
// temporary hack: 0=off,1=warn,2=err --> if 2, alias is disabled
borrowck: uint,
@ -116,6 +131,16 @@ impl session for session {
fn diagnostic() -> diagnostic::span_handler {
self.span_diagnostic
}
fn debugging_opt(opt: uint) -> bool {
(self.opts.debugging_opts & opt) != 0u
}
fn ppregions() -> bool { self.debugging_opt(ppregions) }
fn time_passes() -> bool { self.debugging_opt(time_passes) }
fn count_llvm_insns() -> bool { self.debugging_opt(count_llvm_insns) }
fn time_llvm_passes() -> bool { self.debugging_opt(time_llvm_passes) }
fn stats() -> bool { self.debugging_opt(stats) }
fn no_asm_comments() -> bool { self.debugging_opt(no_asm_comments) }
fn no_verify() -> bool { self.debugging_opt(no_verify) }
}
#[doc = "Some reasonable defaults"]
@ -126,13 +151,8 @@ fn basic_options() -> @options {
optimize: 0u,
debuginfo: false,
extra_debuginfo: false,
verify: false,
lint_opts: [],
save_temps: false,
stats: false,
time_passes: false,
count_llvm_insns: false,
time_llvm_passes: false,
output_type: link::output_type_exe,
addl_lib_search_paths: [],
maybe_sysroot: none,
@ -141,8 +161,7 @@ fn basic_options() -> @options {
test: false,
parse_only: false,
no_trans: false,
no_asm_comments: false,
debug_rustc: false,
debugging_opts: 0u,
borrowck: 0u,
}
}

View File

@ -82,7 +82,7 @@ fn dup_for_join(dest: dest) -> dest {
}
resource icx_popper(ccx: @crate_ctxt) {
if (ccx.sess.opts.count_llvm_insns) {
if ccx.sess.count_llvm_insns() {
vec::pop(*ccx.stats.llvm_insn_ctxt);
}
}
@ -90,7 +90,7 @@ resource icx_popper(ccx: @crate_ctxt) {
impl ccx_icx for @crate_ctxt {
fn insn_ctxt(s: str) -> icx_popper {
#debug("new insn_ctxt: %s", s);
if (self.sess.opts.count_llvm_insns) {
if self.sess.count_llvm_insns() {
*self.stats.llvm_insn_ctxt += [s];
}
icx_popper(self)
@ -522,7 +522,7 @@ fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
helper: glue_helper, name: str)
-> ValueRef {
let _icx = ccx.insn_ctxt("make_generic_glue");
if !ccx.sess.opts.stats {
if !ccx.sess.stats() {
ret make_generic_glue_inner(ccx, t, llfn, helper);
}
@ -1698,7 +1698,7 @@ fn autoderef(cx: block, e_id: ast::node_id,
alt cx.ccx().maps.root_map.find({id:e_id, derefs:derefs}) {
none {}
some(scope_id) {
if !cx.sess().opts.no_asm_comments {
if !cx.sess().no_asm_comments() {
add_comment(cx, #fmt["preserving until end of scope %d",
scope_id]);
}
@ -2495,7 +2495,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
some(scope_id) {
let lv = unrooted(cx, e);
if !cx.sess().opts.no_asm_comments {
if !cx.sess().no_asm_comments() {
add_comment(cx, #fmt["preserving until end of scope %d",
scope_id]);
}
@ -3336,7 +3336,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
let root_loc = alloca(bcx, type_of(bcx.ccx(), ty));
let bcx = unrooted(bcx, e, save_in(root_loc));
if !bcx.sess().opts.no_asm_comments {
if !bcx.sess().no_asm_comments() {
add_comment(bcx, #fmt["preserving until end of scope %d",
scope_id]);
}
@ -3889,7 +3889,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
let _icx = cx.insn_ctxt("trans_stmt");
#debug["trans_stmt(%s)", stmt_to_str(s)];
if (!cx.sess().opts.no_asm_comments) {
if !cx.sess().no_asm_comments() {
add_span_comment(cx, s.span, stmt_to_str(s));
}
@ -4035,7 +4035,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
loop {
#debug["cleanup_and_leave: leaving %s", cur.to_str()];
if !bcx.sess().opts.no_asm_comments {
if !bcx.sess().no_asm_comments() {
add_comment(bcx, #fmt["cleanup_and_leave(%s)", cur.to_str()]);
}
@ -4386,7 +4386,7 @@ fn trans_fn(ccx: @crate_ctxt,
ty_self: self_arg,
param_substs: option<param_substs>,
id: ast::node_id) {
let do_time = ccx.sess.opts.stats;
let do_time = ccx.sess.stats();
let start = if do_time { time::get_time() }
else { {sec: 0i64, nsec: 0i32} };
let _icx = ccx.insn_ctxt("trans_fn");
@ -5397,7 +5397,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
// Translate the metadata.
write_metadata(ccx, crate);
if ccx.sess.opts.stats {
if ccx.sess.stats() {
io::println("--- trans stats ---");
io::println(#fmt("n_static_tydescs: %u",
ccx.stats.n_static_tydescs));
@ -5415,7 +5415,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
}
}
if ccx.sess.opts.count_llvm_insns {
if ccx.sess.count_llvm_insns() {
for ccx.stats.llvm_insns.each { |k, v|
io::println(#fmt("%-7u %s", v, k));
}

View File

@ -7,6 +7,7 @@ import lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
import lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False,
CallConv, TypeKind};
import common::*;
import driver::session::session;
fn B(cx: block) -> BuilderRef {
let b = *cx.fcx.ccx.builder;
@ -15,7 +16,7 @@ fn B(cx: block) -> BuilderRef {
}
fn count_insn(cx: block, category: str) {
if (cx.ccx().sess.opts.count_llvm_insns) {
if cx.ccx().sess.count_llvm_insns() {
let h = cx.ccx().stats.llvm_insns;
let v = cx.ccx().stats.llvm_insn_ctxt;
@ -640,7 +641,7 @@ fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
fn add_span_comment(bcx: block, sp: span, text: str) {
let ccx = bcx.ccx();
if !ccx.sess.opts.no_asm_comments {
if !ccx.sess.no_asm_comments() {
let s = text + " (" + codemap::span_to_str(sp, ccx.sess.codemap)
+ ")";
log(debug, s);
@ -650,7 +651,7 @@ fn add_span_comment(bcx: block, sp: span, text: str) {
fn add_comment(bcx: block, text: str) {
let ccx = bcx.ccx();
if (!ccx.sess.opts.no_asm_comments) {
if !ccx.sess.no_asm_comments() {
let sanitized = str::replace(text, "$", "");
let comment_text = "# " + sanitized;
let asm = str::as_c_str(comment_text, {|c|

View File

@ -237,7 +237,7 @@ fn store_environment(bcx: block,
vec::iteri(bound_values) { |i, bv|
#debug["Copy %s into closure", ev_to_str(ccx, bv)];
if (!ccx.sess.opts.no_asm_comments) {
if !ccx.sess.no_asm_comments() {
add_comment(bcx, #fmt("Copy %s into closure",
ev_to_str(ccx, bv)));
}

View File

@ -12,10 +12,10 @@ import driver::session::session;
fn bound_region_to_str(cx: ctxt, br: bound_region) -> str {
alt br {
br_anon { "&" }
br_named(str) { #fmt["&%s", str] }
br_self if cx.sess.opts.debug_rustc { "&<self>" }
br_self { "&self" }
br_anon { "&" }
br_named(str) { #fmt["&%s", str] }
br_self if cx.sess.ppregions() { "&<self>" }
br_self { "&self" }
}
}
@ -51,7 +51,7 @@ fn region_to_str(cx: ctxt, region: region) -> str {
re_scope(node_id) { #fmt["&%s", re_scope_id_to_str(cx, node_id)] }
re_bound(br) { bound_region_to_str(cx, br) }
re_free(id, br) {
if cx.sess.opts.debug_rustc {
if cx.sess.ppregions() {
// For debugging, this version is sometimes helpful:
#fmt["{%d} %s", id, bound_region_to_str(cx, br)]
} else {