Eliminate many match checks in rustc

This commit is contained in:
Tim Chevalier 2012-08-21 17:22:45 -07:00
parent 0e620ac030
commit 7284969292
12 changed files with 61 additions and 88 deletions

View File

@ -68,19 +68,15 @@ pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool {
// If the fuzzer moves a block-ending-in-semicolon into callee
// position, the pretty-printer can't preserve this even by
// parenthesizing!! See email to marijn.
ast::expr_if(_, _, _) => { false }
ast::expr_block(_) => { false }
ast::expr_match(_, _, _) => { false }
ast::expr_while(_, _) => { false }
ast::expr_if(*) | ast::expr_block(*)
| ast::expr_match(*) | ast::expr_while(*) => { false }
// https://github.com/mozilla/rust/issues/929
ast::expr_cast(_, _) => { false }
ast::expr_assert(_) => { false }
ast::expr_binary(_, _, _) => { false }
ast::expr_assign(_, _) => { false }
ast::expr_assign_op(_, _, _) => { false }
ast::expr_cast(*) | ast::expr_assert(*) |
ast::expr_binary(*) | ast::expr_assign(*) |
ast::expr_assign_op(*) => { false }
ast::expr_fail(option::none) => { false }
ast::expr_fail(option::none) |
ast::expr_ret(option::none) => { false }
// https://github.com/mozilla/rust/issues/953

View File

@ -6,8 +6,8 @@ import ast_util::operator_prec;
fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
match e.node {
ast::expr_if(_, _, _) | ast::expr_match(_, _, _) | ast::expr_block(_)
| ast::expr_while(_, _) | ast::expr_loop(_, _)
ast::expr_if(*) | ast::expr_match(*) | ast::expr_block(_)
| ast::expr_while(*) | ast::expr_loop(*)
| ast::expr_call(_, _, true) => false,
_ => true
}

View File

@ -84,7 +84,7 @@ mod write {
if opts.save_temps {
match opts.output_type {
output_type_bitcode => {
if opts.optimize != 0u {
if opts.optimize != session::No {
let filename = mk_intermediate_name(output, ~"no-opt.bc");
str::as_c_str(filename, |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
@ -107,7 +107,7 @@ mod write {
// Also: Should we expose and use the pass lists used by the opt
// tool?
if opts.optimize != 0u {
if opts.optimize != session::No {
let fpm = mk_pass_manager();
llvm::LLVMAddTargetData(td.lltd, fpm.llpm);
@ -118,8 +118,8 @@ mod write {
llvm::LLVMPassManagerBuilderDispose(FPMB);
llvm::LLVMRunPassManager(fpm.llpm, llmod);
let mut threshold = 225u;
if opts.optimize == 3u { threshold = 275u; }
let mut threshold = 225;
if opts.optimize == session::Aggressive { threshold = 275; }
let MPMB = llvm::LLVMPassManagerBuilderCreate();
llvm::LLVMPassManagerBuilderSetOptLevel(MPMB,
@ -146,11 +146,11 @@ mod write {
let LLVMOptDefault = 2 as c_int; // -O2, -Os
let LLVMOptAggressive = 3 as c_int; // -O3
let mut CodeGenOptLevel = match check opts.optimize {
0u => LLVMOptNone,
1u => LLVMOptLess,
2u => LLVMOptDefault,
3u => LLVMOptAggressive
let mut CodeGenOptLevel = match opts.optimize {
session::No => LLVMOptNone,
session::Less => LLVMOptLess,
session::Default => LLVMOptDefault,
session::Aggressive => LLVMOptAggressive
};
let mut FileType;

View File

@ -1,6 +1,6 @@
// -*- rust -*-
import metadata::{creader, cstore, filesearch};
import session::{session, session_};
import session::{session, session_, OptLevel, No, Less, Default, Aggressive};
import syntax::parse;
import syntax::{ast, codemap};
import syntax::attr;
@ -488,24 +488,24 @@ fn build_session_options(matches: getopts::matches,
link::output_type_llvm_assembly | link::output_type_assembly => (),
_ => debugging_opts |= session::no_asm_comments
}
let opt_level: uint =
let opt_level =
if opt_present(matches, ~"O") {
if opt_present(matches, ~"opt-level") {
early_error(demitter, ~"-O and --opt-level both provided");
}
2u
Default
} else if opt_present(matches, ~"opt-level") {
match getopts::opt_str(matches, ~"opt-level") {
~"0" => 0u,
~"1" => 1u,
~"2" => 2u,
~"3" => 3u,
~"0" => No,
~"1" => Less,
~"2" => Default,
~"3" => Aggressive,
_ => {
early_error(demitter, ~"optimization level needs " +
~"to be between 0-3")
}
}
} else { 0u };
} else { No };
let target =
match target_opt {
none => host_triple(),

View File

@ -70,12 +70,19 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
]
}
enum OptLevel {
No, // -O0
Less, // -O1
Default, // -O2
Aggressive // -O3
}
type options =
// The crate config requested for the session, which may be combined
// with additional crate configurations during the compile process
{crate_type: crate_type,
static: bool,
optimize: uint,
optimize: OptLevel,
debuginfo: bool,
extra_debuginfo: bool,
lint_opts: ~[(lint::lint, lint::level)],
@ -179,6 +186,11 @@ impl session {
fn debugging_opt(opt: uint) -> bool {
(self.opts.debugging_opts & opt) != 0u
}
// This exists to help with refactoring to eliminate impossible
// cases later on
fn impossible_case(sp: span, msg: ~str) -> ! {
self.span_bug(sp, #fmt("Impossible case reached: %s", msg));
}
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) }
@ -199,7 +211,7 @@ fn basic_options() -> @options {
@{
crate_type: session::lib_crate,
static: false,
optimize: 0u,
optimize: No,
debuginfo: false,
extra_debuginfo: false,
lint_opts: ~[],

View File

@ -509,8 +509,8 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers {
-> typeck::vtable_origin {
do self.read_enum(~"vtable_origin") {
do self.read_enum_variant |i| {
match check i {
0u => {
match i {
0 => {
typeck::vtable_static(
do self.read_enum_variant_arg(0u) {
self.read_def_id(xcx)
@ -523,7 +523,7 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers {
}
)
}
1u => {
1 => {
typeck::vtable_param(
do self.read_enum_variant_arg(0u) {
self.read_uint()
@ -533,7 +533,7 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers {
}
)
}
2u => {
2 => {
typeck::vtable_trait(
do self.read_enum_variant_arg(0u) {
self.read_def_id(xcx)
@ -543,6 +543,8 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers {
}
)
}
// hard to avoid - user input
_ => fail ~"bad enum variant"
}
}
}

View File

@ -44,7 +44,7 @@ fn collect_freevars(def_map: resolve3::DefMap, blk: ast::blk)
visit::visit_expr(expr, depth + 1, v);
}
}
ast::expr_fn_block(_, _, _) => {
ast::expr_fn_block(*) => {
visit::visit_expr(expr, depth + 1, v);
}
ast::expr_path(path) => {

View File

@ -191,7 +191,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
// if this is the last use of the variable, then it will be
// a move and not a copy
let is_move = {
match check cx.last_use_map.find(fn_id) {
match cx.last_use_map.find(fn_id) {
some(vars) => (*vars).contains(id),
none => false
}
@ -218,7 +218,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
// Handle any kind bounds on type parameters
do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| {
let bounds = match check e.node {
let bounds = match e.node {
expr_path(_) => {
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
ty::lookup_item_type(cx.tcx, did).bounds

View File

@ -55,23 +55,6 @@ enum lint {
non_camel_case_types
}
// This is pretty unfortunate. We really want some sort of "deriving Enum"
// type of thing.
fn int_to_lint(i: int) -> lint {
match check i {
0 => ctypes,
1 => unused_imports,
2 => while_true,
3 => path_statement,
4 => implicit_copies,
5 => unrecognized_lint,
6 => non_implicitly_copyable_typarams,
7 => vecs_implicitly_copyable,
8 => deprecated_mode,
9 => non_camel_case_types
}
}
fn level_to_str(lv: level) -> ~str {
match lv {
allow => ~"allow",
@ -537,7 +520,7 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl,
}
let fn_ty = ty::node_id_to_type(tcx, id);
match check ty::get(fn_ty).struct {
match ty::get(fn_ty).struct {
ty::ty_fn(fn_ty) => {
let mut counter = 0;
do vec::iter2(fn_ty.inputs, decl.inputs) |arg_ty, arg_ast| {
@ -572,6 +555,8 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl,
}
}
}
_ => tcx.sess.impossible_case(span, ~"check_fn: function has \
non-fn type")
}
}

View File

@ -272,7 +272,7 @@ fn build_closure(bcx0: block,
vec::push(env_vals, env_ref(lv.val, ty, lv.kind));
}
capture::cap_copy => {
let mv = match check ccx.maps.last_use_map.find(id) {
let mv = match ccx.maps.last_use_map.find(id) {
none => false,
some(vars) => (*vars).contains(nid)
};

View File

@ -246,7 +246,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
let ety = ty::expr_ty(cx.tcx, e), llty = type_of::type_of(cx, ety);
let basety = ty::expr_ty(cx.tcx, base);
let v = const_expr(cx, base);
match check (base::cast_type_kind(basety),
match (base::cast_type_kind(basety),
base::cast_type_kind(ety)) {
(base::cast_integral, base::cast_integral) => {
@ -264,6 +264,8 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
else { llvm::LLVMConstFPToUI(v, llty) }
}
_ => cx.sess.impossible_case(e.span,
~"bad combination of types for cast")
}
}
ast::expr_addr_of(ast::m_imm, sub) => {

View File

@ -180,7 +180,7 @@ fn create_compile_unit(cx: @crate_ctxt)
llstr(work_dir),
llstr(env!{"CFG_VERSION"}),
lli1(true), // deprecated: main compile unit
lli1(cx.sess.opts.optimize != 0u),
lli1(cx.sess.opts.optimize != session::No),
llstr(~""), // flags (???)
lli32(0) // runtime version (???)
];
@ -281,7 +281,7 @@ fn size_and_align_of(cx: @crate_ctxt, t: ty::t) -> (int, int) {
shape::llalign_of_pref(cx, llty) as int)
}
fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: ast::prim_ty, span: span)
fn create_basic_type(cx: @crate_ctxt, t: ty::t, span: span)
-> @metadata<tydesc_md> {
let cache = get_cache(cx);
let tg = BasicTypeDescriptorTag;
@ -291,29 +291,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: ast::prim_ty, span: span)
option::none => ()
}
let (name, encoding) = match check ty {
ast::ty_bool => (~"bool", DW_ATE_boolean),
ast::ty_int(m) => match m {
ast::ty_char => (~"char", DW_ATE_unsigned),
ast::ty_i => (~"int", DW_ATE_signed),
ast::ty_i8 => (~"i8", DW_ATE_signed_char),
ast::ty_i16 => (~"i16", DW_ATE_signed),
ast::ty_i32 => (~"i32", DW_ATE_signed),
ast::ty_i64 => (~"i64", DW_ATE_signed)
},
ast::ty_uint(m) => match m {
ast::ty_u => (~"uint", DW_ATE_unsigned),
ast::ty_u8 => (~"u8", DW_ATE_unsigned_char),
ast::ty_u16 => (~"u16", DW_ATE_unsigned),
ast::ty_u32 => (~"u32", DW_ATE_unsigned),
ast::ty_u64 => (~"u64", DW_ATE_unsigned)
},
ast::ty_float(m) => match m {
ast::ty_f => (~"float", DW_ATE_float),
ast::ty_f32 => (~"f32", DW_ATE_float),
ast::ty_f64 => (~"f64", DW_ATE_float)
}
};
let (name, encoding) = (~"uint", DW_ATE_unsigned);
let fname = filename_from_span(cx, span);
let file_node = create_file(cx, fname);
@ -443,8 +421,7 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t,
let file_node = create_file(cx, fname);
//let cu_node = create_compile_unit_metadata(cx, fname);
let uint_t = ty::mk_uint(cx.tcx);
let refcount_type = create_basic_type(cx, uint_t,
ast::ty_uint(ast::ty_u), span);
let refcount_type = create_basic_type(cx, uint_t, span);
let scx = create_structure(file_node, ty_to_str(cx.tcx, outer), 0);
add_member(scx, ~"refcnt", 0, sys::size_of::<uint>() as int,
sys::min_align_of::<uint>() as int, refcount_type.node);
@ -495,8 +472,7 @@ fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t,
let file_node = create_file(cx, fname);
let elem_ty_md = create_ty(cx, elem_t, elem_ty);
let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t), 0);
let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx),
ast::ty_uint(ast::ty_u), vec_ty_span);
let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx), vec_ty_span);
add_member(scx, ~"fill", 0, sys::size_of::<libc::size_t>() as int,
sys::min_align_of::<libc::size_t>() as int, size_t_type.node);
add_member(scx, ~"alloc", 0, sys::size_of::<libc::size_t>() as int,
@ -814,7 +790,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
lli32(0i), //index into virt func
/*llnull()*/ lli32(0), // base type with vtbl
lli32(256), // flags
lli1(cx.sess.opts.optimize != 0u),
lli1(cx.sess.opts.optimize != session::No),
fcx.llfn
//list of template params
//func decl descriptor