diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-02 12:57:27 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-02 12:57:27 +0200 |
| commit | 6c9b90d06a455af08da7ea66977dc4d7d1b4ce1b (patch) | |
| tree | a1b43fb6e6140ce7384bdaf2a439e6b4d287c4aa /src | |
| parent | f8fa574864a5bd54752fc198438f8c53a8ed5ef0 (diff) | |
| download | rust-6c9b90d06a455af08da7ea66977dc4d7d1b4ce1b.tar.gz rust-6c9b90d06a455af08da7ea66977dc4d7d1b4ce1b.zip | |
Be a little more clever about picking columns to match on in trans_alt
This should result in slightly more efficient matching of 'complex' patterns with multiple discriminants in them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans_alt.rs | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs index 899ba437cb1..755dc860793 100644 --- a/src/comp/middle/trans_alt.rs +++ b/src/comp/middle/trans_alt.rs @@ -228,7 +228,37 @@ fn any_box_pat(m: &match, col: uint) -> bool { } type exit_node = {bound: bind_map, from: BasicBlockRef, to: BasicBlockRef}; -type mk_fail = fn() -> BasicBlockRef ; +type mk_fail = fn() -> BasicBlockRef; + +fn pick_col(m: &match) -> uint { + let scores = ivec::init_elt_mut(0u, ivec::len(m.(0).pats)); + for br: match_branch in m { + let i = 0u; + for p: @ast::pat in br.pats { + alt p.node { + ast::pat_lit(_) | ast::pat_tag(_, _) { scores.(i) += 1u; } + _ {} + } + i += 1u; + } + } + let max_score = 0u; + let best_col = 0u; + let i = 0u; + for score: uint in scores { + // Irrefutable columns always go first, they'd only be duplicated in + // the branches. + if score == 0u { ret i; } + // If no irrefutable ones are found, we pick the one with the biggest + // branching factor. + if score > max_score { + max_score = score; + best_col = i; + } + i += 1u; + } + ret best_col; +} fn compile_submatch(bcx: @block_ctxt, m: &match, vals: ValueRef[], f: &mk_fail, exits: &mutable exit_node[]) { @@ -239,10 +269,10 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: ValueRef[], ret; } - // FIXME maybe be clever about picking a column. - let col = 0u; + let col = pick_col(m); let val = vals.(col); - let vals_left = ivec::slice(vals, 1u, ivec::len(vals)); + let vals_left = ivec::slice(vals, 0u, col) + + ivec::slice(vals, col + 1u, ivec::len(vals)); let ccx = bcx.fcx.lcx.ccx; let pat_id = 0; for br: match_branch in m { |
